Как определить, равны ли 2 значения в строке? [Дубликат]

let и const имеют две большие отличия от var:

  1. Они являются блочным областью .
  2. Доступ к var до его объявления имеет результат undefined; доступ к let или const, прежде чем он будет объявлен бросками ReferenceError:

console.log(aVar); // undefined
console.log(aLet); // causes ReferenceError: aLet is not defined
var aVar = 1;
let aLet = 2;

примеры, что let объявления (и const, которые работают одинаково) могут не быть подняты , так как aLet не существует, пока ему не присвоено значение.

Это не так, однако let и const подняты (например, var, class и function), но есть период между вводом области и объявлением там, где они не могут быть доступны. Этот период является временной мертвой зоной (TDZ).

TDZ заканчивается, когда aLet объявлен объявлен , а не назначен :

//console.log(aLet)  // would throw ReferenceError

let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10

Этот пример показывает, что let поднят:

let x = 'outer value';
(function() {
  // start TDZ for x
  console.log(x);
  let x = 'inner value'; // declaration ends TDZ for x
}());

Кредит: временная мертвая зона (TDZ) demystified

Доступ к x во внутренней области все еще вызывает ReferenceError. Если let не были подняты, он будет записывать outer value.

TDZ - это хорошо, потому что он помогает выделить ошибки - доступ к значению до того, как он был объявлен, редко преднамерен.

TDZ также применяется к аргументам функции по умолчанию. Аргументы оцениваются слева направо, и каждый аргумент находится в TDZ до тех пор, пока он не назначен:

// b is in TDZ until its value is assigned
function testDefaults(a=b, b) { }
testDefaults(undefined, 1); // throws ReferenceError because the evaluation of a reads b before it has been evaluated.

TDZ не включен по умолчанию в трансляторе babel.js . Включите режим «высокого соответствия», чтобы использовать его в REPL . Поставьте флаг es6.spec.blockScoping, чтобы использовать его с CLI или в качестве библиотеки.

Рекомендуемое дополнительное чтение: TDZ demystified и ES6 Let, Const и «Temporal Dead» Зона "(TDZ) в глубину .

31
задан Alex Riley 2 January 2017 в 12:29
поделиться

6 ответов

Вы можете использовать np.where . Если cond является булевым массивом, а A и B являются массивами, тогда

C = np.where(cond, A, B)

определяет C равным A, где cond имеет значение True, а B, где cond - False.

import numpy as np
import pandas as pd

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three'])
                     , df['one'], np.nan)

дает

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03  NaN
2   8    5     0  NaN

Если у вас более одного условия, вы можете использовать np.select . Например, если вы хотите df['que'] равняться df['two'], когда df['one'] < df['two'], то

conditions = [
    (df['one'] >= df['two']) & (df['one'] <= df['three']), 
    df['one'] < df['two']]

choices = [df['one'], df['two']]

df['que'] = np.select(conditions, choices, default=np.nan)

дает

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03   70
2   8    5     0  NaN

Если мы можем предположить, что df['one'] >= df['two'], когда df['one'] < df['two'] является False, тогда условия и варианты могут быть упрощены до

conditions = [
    df['one'] < df['two'],
    df['one'] <= df['three']]

choices = [df['two'], df['one']]

(Предположение может быть неверным, если df['one'] или df['two'] содержат NaNs.)


Обратите внимание, что

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

определяет DataFrame со строковыми значениями. Поскольку они выглядят как числовые, вам может быть лучше преобразовать эти строки в float:

df2 = df.astype(float)

Это изменяет результаты, однако, поскольку строки сравниваются по каждому символу, а численные значения поплавков - численно.

In [61]: '10' <= '4.2'
Out[61]: True

In [62]: 10 <= 4.2
Out[62]: False
48
ответ дан unutbu 20 August 2018 в 08:56
поделиться

Вы можете использовать .equals для столбцов или целых фреймов данных.

df['col1'].equals(df['col2'])

Если они равны, этот оператор вернет True, else False.

12
ответ дан Alberto Garcia-Raboso 20 August 2018 в 08:56
поделиться

Одним из способов является использование булевой последовательности для индексации столбца df['one']. Это дает вам новый столбец, в котором записи True имеют то же значение, что и df['one'], а значения False равны NaN.

Булевы серии заданы только вашим if (хотя для & необходимо использовать and):

>>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])]
>>> df
    one two three   que
0   10  1.2 4.2      10
1   15  70  0.03    NaN
2   8   5   0       NaN

Если вы хотите, чтобы значения NaN были заменены другими значениями, вы можете использовать fillna в новом столбце que. Я использовал 0 вместо пустой строки здесь:

>>> df['que'] = df['que'].fillna(0)
>>> df
    one two three   que
0   10  1.2   4.2    10
1   15   70  0.03     0
2    8    5     0     0
7
ответ дан Alex Riley 20 August 2018 в 08:56
поделиться

Вы можете использовать apply () и сделать что-то вроде этого

df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1)

или если вы предпочитаете не использовать лямбда

def que(x):
    if x['one'] >= x['two'] and x['one'] <= x['three']:
        return x['one']
    else:
        ''
df['que'] = df.apply(que, axis=1)
18
ответ дан Bob Haffner 20 August 2018 в 08:56
поделиться
  • 1
    Я подозреваю, что это, вероятно, немного медленнее, чем другие опубликованные подходы, поскольку он не использует преимущества векторизованных операций, разрешенных пандами. – Marius 14 December 2014 в 23:51
  • 2
    Может быть. Мне нравится читаемость, хотя – Bob Haffner 15 December 2014 в 00:08
  • 3
    Могли бы добавить ответ, где def используется вместо лямбда, спасибо – Merlin 15 December 2014 в 00:14
  • 4
    c'mon, lambdas классные ;-) – Bob Haffner 15 December 2014 в 00:22
  • 5
    @BobHaffner: lambda не читаются при использовании сложных операторов if / then / else. – Merlin 15 December 2014 в 00:31

Оберните каждое отдельное условие в круглых скобках, а затем используйте оператор & для объединения условий:

df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one']

Вы можете заполнить несоответствующие строки, просто используя ~ (" не ") для инвертирования соответствия:

df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = ''

Вам нужно использовать & и ~, а не and и not, поскольку работают операторы & и ~ элемент за элементом.

Конечный результат:

df
Out[8]: 
  one  two three que
0  10  1.2   4.2  10
1  15   70  0.03    
2   8    5     0  
4
ответ дан Marius 20 August 2018 в 08:56
поделиться
0
ответ дан Nic Scozzaro 31 October 2018 в 07:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: