对于数据框,我有一个名为 TM52_fail
2
1
-
1 & 2
1 & 2 & 3
-
-
3
etc.
我想创建一个名为 TM52_fail_norm
的附加列,其内容取决于 TM52_fail
列的内容。
我的尝试(包括条件填充):
def str_to_number(x):
if x=="1" or x=="2" or x=="3":
return 1
elif x=="1 & 2" or x=="2 & 3" or x=="1 & 3":
return 2
elif x=="1 & 2 & 3":
return 3
else:
return 0
df['TM52_fail_norm'] = ""
df['TM52_fail_norm'].apply(lambda x: str_to_number(x for x in df['TM52_fail']))
返回一个空列(我认为是 df['TM52_fail_norm'] = ""
的结果)。
最佳答案
我认为你需要通过 astype
转换为字符串然后应用函数str_to_number
:
df['new'] = df['TM52_fail_norm'].astype(str).apply(str_to_number)
print (df)
TM52_fail_norm new
0 2 1
1 1 1
2 - 0
3 1 & 2 2
4 1 & 2 & 3 3
5 - 0
6 - 0
7 3 1
另一个解决方案 map
通过 dict
,最后需要 fillna
通过 0
并转换为 int
:
d = {'1':1,'2':1,'3':1,'1 & 2':2, '2 & 3':2, '1 & 3':2,'1 & 2 & 3':3}
df['new'] = df['TM52_fail_norm'].map(d)
df['new'] = df['new'].fillna(0).astype(int)
print (df)
TM52_fail_norm new
0 2 1
1 1 1
2 - 0
3 1 & 2 2
4 1 & 2 & 3 3
5 - 0
6 - 0
7 3 1
时间:
#[800000 rows x 1 columns]
df = pd.concat([df]*100000).reset_index(drop=True)
In [315]: %timeit (jez1(df))
10 loops, best of 3: 63 ms per loop
In [316]: %timeit (df['TM52_fail_norm'].astype(str).apply(str_to_number))
1 loop, best of 3: 518 ms per loop
#http://stackoverflow.com/a/40176883/2901002
In [345]: %timeit (df.TM52_fail_norm.str.count('\d+'))
1 loop, best of 3: 707 ms per loop
def jez1(df):
d = {'1':1,'2':1,'3':1,'1 & 2':2, '2 & 3':2, '1 & 3':2,'1 & 2 & 3':3}
df['new'] = df['TM52_fail_norm'].map(d)
df['new'] = df['new'].fillna(0).astype(int)
return (df)
print (jez1(df))
关于python - 根据同一 pandas 数据框中的其他列为列分配值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40174764/