对于 pandas
,我正在寻找一种方法,根据A列中相应行的子串,将条件值写入B列中的每一行。
所以,如果细胞在 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'])
在您错误地创建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
或者在创建数据帧之前对数据进行逻辑处理:
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
你可以用 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:...)
。使用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
另外,填充 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']
。