我有一个数据框,我正在尝试根据外部参考表中的信息进行更新(目前这是一个很小的~20条目csv),而且我很难搞清楚如何获取它工作。
数据框如下所示:
id company value1 value2
1 foo 10.00 0.00
2 bar 10.00 0.00
3 lorem 15.00 0.00
4 ipsum 10.00 0.00
5 foo 50.00 0.00
6 lorem 40.00 0.00
7 foo 0.00 0.00
参考表csv包含乘以value1乘以得到value2的百分比,就像这样(它们原来是小数,但是vd = pd.read_csv('$ name.csv',index_col = 0).to_dict()导致浮动点问题,所以我更改了参考表):
company percentage
foo 15
bar 50
ipsum 40
我正在寻找输出显示如下:
id company value1 value2
1 foo 10.00 1.50
2 bar 10.00 5.00
3 lorem 15.00 15.00
4 ipsum 10.00 4.00
5 foo 50.00 7.50
6 lorem 40.00 40.00
7 foo 0.00 0.00
目前,我将引用表导入字典(作为整数),但是当我将其与数据帧匹配时,结果(value2)将返回NaN。我认为我的问题可能在于匹配的代码,目前看起来像这样:
df['value2'] = df['value1'] * (df["company"].map(vd)/100)
我在这里走在正确的轨道上吗?这是我第一次使用大熊猫,所以我可能会遗漏一些明显的东西。
谢谢!
编辑:意外忘记混淆一个变量。 “vd”只是导入后的字典名称。
答案 0 :(得分:2)
map
是做你正在做的事情的最快方式。但这里有几个替代方案,以及它们的表现。
<强>设置强>
首先,df
-
df
id company value1 value2
0 1 foo 10.0 0.0
1 2 bar 10.0 0.0
2 3 lorem 15.0 0.0
3 4 ipsum 10.0 0.0
4 5 foo 50.0 0.0
5 6 lorem 40.0 0.0
接下来,vd
-
vd = pd.read_csv('$name.csv')
vd = vd.set_index('company').percentage
或者,
vd = pd.read_csv('$name.csv', index_col=0, squeeze=True) # @ayhan's suggestion
vd
company
foo 15
bar 50
ipsum 40
Name: percentage, dtype: int64
选项1
map
df.value2 = df.value1 * df.company.map(vd).fillna(100).div(100)
df
id company value1 value2
0 1 foo 10.0 1.5
1 2 bar 10.0 5.0
2 3 lorem 15.0 15.0
3 4 ipsum 10.0 4.0
4 5 foo 50.0 7.5
5 6 lorem 40.0 40.0
选项2
replace
v = pd.to_numeric(df.company.replace(vd), errors='coerce')
df.value2 = df.value1 * v.fillna(100) / 100
df
id company value1 value2
0 1 foo 10.0 1.5
1 2 bar 10.0 5.0
2 3 lorem 15.0 15.0
3 4 ipsum 10.0 4.0
4 5 foo 50.0 7.5
5 6 lorem 40.0 40.0
选项3
merge
df = df.merge(
(vd / 100).to_frame(),
left_on='company',
right_index=True,
how='left'
).fillna(1)
df.value2 = df.value1 * df.percentage
del df['percentage']
df
id company value1 value2
0 1 foo 10.0 1.5
1 2 bar 10.0 5.0
2 3 lorem 15.0 15.0
3 4 ipsum 10.0 4.0
4 5 foo 50.0 7.5
5 6 lorem 40.0 40.0
<强>性能强>
df = pd.concat([df] * 10000, ignore_index=True)
%timeit df.value1 * df.company.map(vd).fillna(100).div(100)
100 loops, best of 3: 6.07 ms per loop
%timeit df.value1 * pd.to_numeric(df.company.replace(vd), errors='coerce').fillna(100) / 100
10 loops, best of 3: 65.6 ms per loop
%%timeit
df2 = df.merge((vd / 100).to_frame(), left_on='company', right_index=True, how='left').fillna(1)
df2.value2 = df2.value1 * df2.percentage
del df2['percentage']
100 loops, best of 3: 13.1 ms per loop
map
在这里是明显的赢家。