迭代pandas数据帧并更新值 - AttributeError:无法设置属性

时间:2017-04-05 05:54:15

标签: python pandas dataframe

我正在尝试迭代pandas数据帧并在条件满足时更新值但是我收到错误。

blur

3 个答案:

答案 0 :(得分:22)

首先在pandas中迭代是可能的,但速度非常慢,因此使用了另一种向量化解决方案。

如果您需要迭代,我认为您可以使用iterrows

for idx, row in df.iterrows():
    if  df.loc[idx,'Qty'] == 1 and df.loc[idx,'Price'] == 10:
        df.loc[idx,'Buy'] = 1

但更好的是使用矢量化解决方案 - 通过布尔掩码设置值loc

mask = (df['Qty'] == 1) & (df['Price'] == 10)
df.loc[mask, 'Buy'] = 1

或使用mask的解决方案:

df['Buy'] = df['Buy'].mask(mask, 1)

或者如果您需要if...else使用numpy.where

df['Buy'] = np.where(mask, 1, 0)

<强>样品

按条件设置值:

df = pd.DataFrame({'Buy': [100, 200, 50], 
                   'Qty': [5, 1, 1], 
                   'Name': ['apple', 'pear', 'banana'], 
                   'Price': [1, 10, 10]})

print (df)
   Buy    Name  Price  Qty
0  100   apple      1    5
1  200    pear     10    1
2   50  banana     10    1
mask = (df['Qty'] == 1) & (df['Price'] == 10)


df['Buy'] = df['Buy'].mask(mask, 1)
print (df)
   Buy    Name  Price  Qty
0  100   apple      1    5
1    1    pear     10    1
2    1  banana     10    1
df['Buy'] = np.where(mask, 1, 0)
print (df)
   Buy    Name  Price  Qty
0    0   apple      1    5
1    1    pear     10    1
2    1  banana     10    1

答案 1 :(得分:9)

好的,如果您打算在df中设置值,则需要跟踪index值。

选项1
使用itertuples

# keep in mind `row` is a named tuple and cannot be edited
for line, row in enumerate(df.itertuples(), 1):  # you don't need enumerate here, but doesn't hurt.
    if row.Qty:
        if row.Qty == 1 and row.Price == 10:
            df.set_value(row.Index, 'Buy', 1)

选项2
使用iterrows

# keep in mind that `row` is a `pd.Series` and can be edited...
# ... but it is just a copy and won't reflect in `df`
for idx, row in df.iterrows():
    if row.Qty:
        if row.Qty == 1 and row.Price == 10:
            df.set_value(idx, 'Buy', 1)

选项3
使用get_value

的直线循环
for idx in df.index:
    q = df.get_value(idx, 'Qty')
    if q:
        p = df.get_value(idx, 'Price')
        if q == 1 and p == 10:
            df.set_value(idx, 'Buy', 1)

答案 2 :(得分:1)

pandas.DataFrame.set_value方法自0.21.0 pd.DataFrame.set_value以来已弃用

使用pandas.Dataframe.at

for index, row in df.iterrows():
        if row.Qty and row.Qty == 1 and row.Price == 10:
            df.at[index,'Buy'] = 1