Pandas: если строка в столбце A содержит "x", напишите "y" для строки в столбце B
Для pandas
я ищу способ записи условных значений в каждую строку в столбце B на основе подстрок для соответствующих строк в столбце A.
Поэтому, если ячейка в A
содержит "BULL"
, напишите "Long"
в B
Или, если ячейка в A
содержит "BEAR"
, напишите "Short"
на B
Желаемый результат:
A B
"BULL APPLE X5" "Long"
"BEAR APPLE X5" "Short"
"BULL APPLE X5" "Long"
B первоначально пусто: df = pd.DataFrame([['BULL APPLE X5',''],['BEAR APPLE X5',''],['BULL APPLE X5','']],columns=['A','B'])
Ответы
Ответ 1
Ваш код будет ошибочным при неправильном создании Dataframe, просто создайте один столбец A
затем добавьте B
на основе A
:
import pandas as pd
df = pd.DataFrame(["BULL","BEAR","BULL"], columns=['A'])
df["B"] = ["Long" if ele == "BULL" else "Short" for ele in df["A"]]
print(df)
A B
0 BULL Long
1 BEAR Short
2 BULL Long
Или вы логики с данными перед созданием dataframe:
import pandas as pd
data = ["BULL","BEAR","BULL"]
data2 = ["Long" if ele == "BULL" else "Short" for ele in data]
df = pd.DataFrame(list(zip(data, data2)), columns=['A','B'])
print(df)
A B
0 BULL Long
1 BEAR Short
2 BULL Long
Для вашего редактирования:
df = pd.DataFrame([['BULL APPLE X5',''],['BEAR APPLE X5',''],['BULL APPLE X5','']], columns=['A','B'])
df["B"] = df["A"].map(lambda x: "Long" if "BULL" in x else "Short" if "BEAR" in x else "")
print(df)
A B
0 BULL APPLE X5 Long
1 BEAR APPLE X5 Short
2 BULL APPLE X5 Long
Или просто добавьте столбец после:
df = pd.DataFrame(['BULL APPLE X5','BEAR APPLE X5','BLL APPLE X5'], columns=['A'])
df["B"] = df["A"].map(lambda x: "Long" if "BULL" in x else "Short" if "BEAR" in x else "")
print(df)
Или использование содержит:
df = pd.DataFrame([['BULL APPLE X5',''],['BEAR APPLE X5',''],['BULL APPLE X5','']], columns=['A','B'])
df["B"][df['A'].str.contains("BULL")] = "Long"
df["B"][df['A'].str.contains("BEAR")] = "Short"
print(df)
0 BULL APPLE X5 Long
1 BEAR APPLE X5 Short
2 BULL APPLE X5 Long
Ответ 2
Вы можете использовать str.extract
для поиска шаблона регулярного выражения BULL|BEAR
, а затем использовать Series.map
для замены этих строк Long
или Short
:
In [50]: df = pd.DataFrame([['BULL APPLE X5',''],['BEAR APPLE X5',''],['BULL APPLE X5','']],columns=['A','B'])
In [51]: df['B'] = df['A'].str.extract(r'(BULL|BEAR)').map({'BULL':'Long', 'BEAR':'Short'})
In [55]: df
Out[55]:
A B
0 BULL APPLE X5 Long
1 BEAR APPLE X5 Short
2 BULL APPLE X5 Long
Однако формирование промежуточной серии с str.extract
довольно медленно по сравнению с df['A'].map(lambda x:...)
str.extract
df['A'].map(lambda x:...)
. Используя IPython %timeit
для времени тестов,
In [5]: df = pd.concat([df]*10000)
In [6]: %timeit df['A'].str.extract(r'(BULL|BEAR)').map({'BULL':'Long', 'BEAR':'Short'})
10 loops, best of 3: 39.7 ms per loop
In [7]: %timeit df["A"].map(lambda x: "Long" if "BULL" in x else "Short" if "BEAR" in x else "")
100 loops, best of 3: 4.98 ms per loop
Большая часть времени проводится в str.extract
:
In [8]: %timeit df['A'].str.extract(r'(BULL|BEAR)')
10 loops, best of 3: 37.1 ms per loop
в то время как вызов Series.map
относительно быстр:
In [9]: x = df['A'].str.extract(r'(BULL|BEAR)')
In [10]: %timeit x.map({'BULL':'Long', 'BEAR':'Short'})
1000 loops, best of 3: 1.82 ms per loop
Ответ 3
Кроме того, для df['B']
вы можете попробовать метод ниже:
def applyFunc(s):
if s == 'BULL':
return 'Long'
elif s == 'BEAR':
return 'Short'
return ''
df['B'] = df['A'].apply(applyFunc)
df
>>
A B
0 BULL Long
1 BEAR Short
2 BULL Long
Что делает функция apply
, то для каждого значения строки df['A']
она вызывает функцию applyFunc
с параметром в качестве значения этой строки, а возвращаемое значение помещается в ту же строку для df['B']
, то, что действительно происходит за сценой, немного отличается, но значение прямо не помещается в df['B']
а создается новая Series
и в конце новая серия назначается df['B']
.