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 沒有變化,最後一行代碼為啥沒效果,有大神能說一下原因嗎(搜瞭一通沒啥結果。。),多謝~

第 1 條附言  ·  1 天前 循環裡還有兩句代碼沒寫全,抱歉~
如下:
```
won_last[hteam] = row['homewin']
won_last[vteam] = not row['homewin']
```
row['homewin'] 類型是 bool。
已邀請:

lol小樓

贊同來自:

應該這樣寫是可以的 dset.assign(hlastwin=lambda x: won_last[x.home], vlastwin=lambda x: won_last[x.visitor])

煙囪設計規範

贊同來自:

iloc/loc 等一般隻能用於讀取,應該隻是類似一個 copy 的性質
改變 df 要另外賦值

另外,這樣輪循有點笨啊,應該整列復制,或者 join/merge

李易峰

贊同來自:

```
dest['hlastwin'] = dest['home'].map(lambda h: won_last[h])
```

大概是這麼一個思路

田亮微博

贊同來自:

上面幾樓都說瞭,我加一句,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]

fluent教程

贊同來自:

```
import pandas as pd
import numpy as np

won_last = pd.DataFrame({'lastwin':["lastwin_{}".format(i) for i in range(10000)]})
dset = pd.DataFrame(np.random.randint(10000, size=(10000, 2)),
columns=['home', 'visitor'])
In [2]:
%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")

7.16 ms ± 340 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


In [3]:
%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])
355 ms ± 34.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

```

風行雲

贊同來自:

@imn1 按行遍歷是因為 won_last 字典不斷變動,我把代碼補全一下。。

新浪微薄

贊同來自:

你問的 iloc 那句不起作用,可以按樓上說的改,比如:

dset[i, 'hlastwin'] = won_last[hteam]

另外,看你的程序意思是每次循環裡要給當前 row 填一個“主隊上次贏”,“客隊上次贏”這樣的字段?
由於每個 row 都依賴上一次某條的記錄,所以 merge 不太容易吧。
如果是這個情況的話,用 pandas 原地修改 dset 會比較慢,可以新開一個 list 來存;或者原始數據不放 pandas,直接用 list。
這樣用 for 循環遍歷的表現可能會好一些。

最後,這樣一邊迭代 dset,同時一邊又修改 dset,感覺不太好。建議迭代 dset 的時候不要原地修改,而是將新 row 的數據放在其他變量裡。

要回復問題請先登錄註冊