Python中pandas代码请教
for i, row in dset.iterrows():
hteam = row['home']
vteam = row['visitor']
row['hlastwin'] = won_last[hteam]
row['vlastwin'] = won_last[vteam]
dset.iloc[i] = row
如上,dset 是一个 DataFrame,遍历每行并为每行增加两个元素,期望遍历结束后 dset 应该增加两列,但实际 dset 没有变化,最后一行代码为啥没效果,有大神能说一下原因吗(搜了一通没啥结果。。),多谢~
Python中pandas代码请教
应该这样写是可以的 dset.assign(hlastwin=lambda x: won_last[x.home], vlastwin=lambda x: won_last[x.visitor])
我无法理解你的问题
iloc/loc 等一般只能用于读取,应该只是类似一个 copy 的性质
改变 df 要另外赋值
另外,这样轮循有点笨啊,应该整列复制,或者 join/merge
<br>dest['hlastwin'] = dest['home'].map(lambda h: won_last[h])<br>
大概是这么一个思路
上面几楼都说了,我加一句,pandas 是调用 numpy 的接口的,因此不要自己写循环。自己的循环是没有 Pandas 里面的对 dataframe 的操作快的。
dset.loc[:, ‘hlastwin’] = [won_last[i] for i in dset[‘home’].values]
dset.loc[:, ‘vlastwin’] = [won_last[i] for i in dset[‘visitor’].values]
<br>import pandas as pd<br>import numpy as np<br><br>won_last = pd.DataFrame({'lastwin':["lastwin_{}".format(i) for i in range(10000)]})<br>dset = pd.DataFrame(np.random.randint(10000, size=(10000, 2)),<br> columns=['home', 'visitor'])<br>In [2]:<br>%timeit dset.merge(won_last, left_on='home', right_index=True,how='left').merge(won_last, left_on='visitor', right_index=True,how='left', suffixes="hv")<br><br>7.16 ms ± 340 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)<br><br><br>In [3]:<br>%timeit dset.assign(hlastwin=lambda x: [won_last.lastwin[ii] for ii in x.home], vlastwin=lambda x: [won_last.lastwin[ii] for ii in x.visitor])<br>355 ms ± 34.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)<br><br>
按行遍历是因为 won_last 字典不断变动,我把代码补全一下。。
你问的 iloc 那句不起作用,可以按楼上说的改,比如:
dset[i, ‘hlastwin’] = won_last[hteam]
另外,看你的程序意思是每次循环里要给当前 row 填一个“主队上次赢”,“客队上次赢”这样的字段?
由于每个 row 都依赖上一次某条的记录,所以 merge 不太容易吧。
如果是这个情况的话,用 pandas 原地修改 dset 会比较慢,可以新开一个 list 来存;或者原始数据不放 pandas,直接用 list。
这样用 for 循环遍历的表现可能会好一些。
最后,这样一边迭代 dset,同时一边又修改 dset,感觉不太好。建议迭代 dset 的时候不要原地修改,而是将新 row 的数据放在其他变量里。

