我在DataFrame(5000000x100)中有三列稀疏非空,如此(非空值是货币代码):
NaN EUR EUR
NaN NaN NaN
NaN NaN NaN
EUR NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN GBP NaN
NaN NaN NaN
NaN NaN NaN
USD NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN EUR EUR
我还有一本字典,其转换率为欧元,如下所示:
{'USD':0.8499 , 'EUR': 1 , 'GBP': 1.135}
我希望为每一行创建另一个具有相应转化率的列(我们可以假设一行只有一种货币的实例)EG:
NaN EUR EUR 1
NaN NaN NaN NaN
NaN NaN NaN NaN
EUR NaN NaN 1
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN GBP NaN 1.135
NaN NaN NaN NaN
NaN NaN NaN NaN
USD NaN NaN 0.8499
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN NaN NaN NaN
NaN EUR EUR 1
我可以使用map实现单个列的预期结果。 EG:
res = s.map(conversion_rate_dictionary)
这将给出一个小例子:
s res
NaN NaN
EUR 1
GBP 1.135
USD 0.849
NaN NaN
我很难直接或通过在每个列上组合地图的结果来获得所需的结果。感谢您的任何建议
答案 0 :(得分:1)
使用replace
与ffill
一起转发NaN
,然后按DataFrame.iloc
选择最后一栏:
d = {'USD':0.8499 , 'EUR': 1 , 'GBP': 1.135}
df['new'] = df.replace(d).ffill(axis=1).iloc[:, -1]
print (df)
a b c new
0 NaN EUR EUR 1.0000
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 EUR NaN NaN 1.0000
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
6 NaN GBP NaN 1.1350
7 NaN NaN NaN NaN
8 NaN NaN NaN NaN
9 USD NaN NaN 0.8499
10 NaN NaN NaN NaN
11 NaN NaN NaN NaN
12 NaN NaN NaN NaN
13 NaN EUR EUR 1.0000
详情:
print (df.replace(d).ffill(axis=1))
a b c
0 NaN 1.0000 1.0000
1 NaN NaN NaN
2 NaN NaN NaN
3 1.0000 1.0000 1.0000
4 NaN NaN NaN
5 NaN NaN NaN
6 NaN 1.1350 1.1350
7 NaN NaN NaN
8 NaN NaN NaN
9 0.8499 0.8499 0.8499
10 NaN NaN NaN
11 NaN NaN NaN
12 NaN NaN NaN
13 NaN 1.0000 1.0000
大型DataFrame
中的Numpy解决方案更快:
d = {'USD':0.8499 , 'EUR': 1 , 'GBP': 1.135}
a = df.replace(d).values
m = ~np.isnan(a)
b = a[np.arange(m.shape[0]), m.shape[1]-m[:,::-1].argmax(1)-1]
print (b)
[ 1. nan nan 1. nan nan 1.135 nan nan
0.8499 nan nan nan 1. ]
df['new'] = b
print (df)
a b c new
0 NaN EUR EUR 1.0000
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 EUR NaN NaN 1.0000
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
6 NaN GBP NaN 1.1350
7 NaN NaN NaN NaN
8 NaN NaN NaN NaN
9 USD NaN NaN 0.8499
10 NaN NaN NaN NaN
11 NaN NaN NaN NaN
12 NaN NaN NaN NaN
13 NaN EUR EUR 1.0000