pandas 基于布尔条件对数据框进行切片,乘以常数并将值赋回数据框,不起作用

8fq7wneg  于 2023-04-19  发布在  其他
关注(0)|答案(2)|浏览(104)

我尝试基于布尔条件对 Dataframe 进行切片,将序列乘以常数,并将结果赋值回原始 Dataframe 。除了将其赋值回原始 Dataframe 之外,我可以完成所有这些操作。
下面是一个例子:

df = {'a':[10,20,30,40,50,60], 'b':[110,120,130,140,150,160], 'c':[210,220,230,240,250,260]}
df = pd.DataFrame(df)
df
    a   b   c
0   10  110 210
1   20  120 220
2   30  130 230
3   40  140 240
4   50  150 250
5   60  160 260

# I can slice it:
df.loc[df['a']>30, 'a'].iloc[0:2] 
3    40
4    50
Name: a, dtype: int64

# I can multiply it by a constant:
df.loc[df['a']>30, 'a'].iloc[0:2] * 2
3     80
4    100
Name: a, dtype: int64

# But, trying to assign it back doesn't work:
df.loc[df['a']>30, 'a'].iloc[0:2] = df.loc[df['a']>30, 'a'].iloc[0:2] * 2 
df
    a   b   c
0   10  110 210
1   20  120 220
2   30  130 230
3   40  280 240
4   50  300 250
5   60  160 260

为什么我错过了什么

ecfdbz9o

ecfdbz9o1#

是的,你正在创建一个链式赋值。其中pandas是在内存中创建一个新对象,你正在更新它,它不会流回原始的 Dataframe ,因为有多个__getitem__调用。
这里有一种方法,使用signle.loc和赋值运算符*=

df.loc[df[(df['a']>30)].head(2).index,'a'] *= 2

输出:

a    b    c
0   10  110  210
1   20  120  220
2   30  130  230
3   80  140  240
4  100  150  250
5   60  160  260
ozxc1zmp

ozxc1zmp2#

您可以通过创建一个临时变量来解决此问题,该临时变量保存由loc查询返回的dataframe:

import pandas as pd

df = {'a': [10, 20, 30, 40, 50, 60], 'b': [110, 120, 130,
                                           140, 150, 160], 'c': [210, 220, 230, 240, 250, 260]}
df = pd.DataFrame(df)

# Hold dataframe returned from query
tmp_slice = df.loc[df['a'] > 30, 'a']
# Apply changes to slice of queried dataframe
tmp_slice.iloc[0:2] = df.loc[df['a'] > 30, 'a'].iloc[0:2] * 2

# Apply they modified queried dataframe back to original dataframe
df.loc[df['a'] > 30, 'a'] = tmp_slice

df输出:

a    b    c
0   10  110  210
1   20  120  220
2   30  130  230
3   80  140  240
4  100  150  250
5   60  160  260

相关问题