Python 迭代 Pandas 数据框并更新值 - AttributeError: can't set attribute

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43222878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:40:07  来源:igfitidea点击:

iterate over pandas dataframe and update the value - AttributeError: can't set attribute

pythonpandasdataframe

提问by Sun

I am trying to iterate over a pandas dataframe and update the value if condition is met but i am getting an error.

我正在尝试遍历 Pandas 数据帧并在满足条件时更新值,但出现错误。

for line, row in enumerate(df.itertuples(), 1):
    if row.Qty:
        if row.Qty == 1 and row.Price == 10:
            row.Buy = 1
AttributeError: can't set attribute

回答by jezrael

First iterating in pandas is possible, but very slow, so another vectorized solution are used.

可以先在 Pandas 中进行迭代,但速度很慢,因此使用了另一种矢量化解决方案。

I think you can use iterrowsif you need iterating:

我认为您可以iterrows在需要迭代时使用:

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

But better is to use vectorized solutions – set value by boolean mask with loc:

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

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

Or solution with mask:

或解决方案mask

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

Or if you need if...elseuse numpy.where:

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

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

Samples.

样品

Set values by conditions:

按条件设置值:

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

回答by piRSquared

Ok, if you intend to set values in dfthen you need track the indexvalues.

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

option 1
using itertuples

选项 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)

option 2
using iterrows

选项 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)

option 3
using straight up loop with get_value

选项 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)

回答by Saurabh

pandas.DataFrame.set_value method is deprecated as of 0.21.0 pd.DataFrame.set_value

pandas.DataFrame.set_value 方法从 0.21.0开始弃用pd.DataFrame.set_value

Use pandas.Dataframe.at

使用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