Python:Pandas Dataframe如何将整个列与标量相乘

lab*_*shr 49 python pandas chained-assignment

如何将数据帧的给定列的每个元素与标量相乘?(我试过看SO,但似乎找不到合适的解决方案)

做类似的事情:

df['quantity'] *= -1 # trying to multiply each row's quantity column with -1
Run Code Online (Sandbox Code Playgroud)

给我一个警告:

A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
Run Code Online (Sandbox Code Playgroud)

注意:如果可能的话,我不想迭代数据帧并执行类似的操作...因为我认为整个列上的任何标准数学运算都应该可以不必编写循环:

for idx, row in df.iterrows():
    df.loc[idx, 'quantity'] *= -1
Run Code Online (Sandbox Code Playgroud)

编辑:

我正在跑0.16.2熊猫

完整的痕迹:

 SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[item] = s
Run Code Online (Sandbox Code Playgroud)

mas*_*kar 47

尝试使用应用功能.

df['quantity'] = df['quantity'].apply(lambda x: x*-1)
Run Code Online (Sandbox Code Playgroud)

  • @ALollz 你建议什么替代方案? (4认同)
  • Series.apply是一个循环,不应用于简单的乘法。不必要的lambda只会使情况更糟。 (3认同)
  • 与循环相比,这非常优雅,尽管我仍然可以看到SettingWithCopyWarning (2认同)

lab*_*shr 42

经过一些研究后,这是答案:

df.loc[:,'quantity'] *= -1 #seems to prevent SettingWithCopyWarning 
Run Code Online (Sandbox Code Playgroud)

  • 在Pandas中看到了多少陷阱,看起来有多么简单:R:`require(data.table); DF [,数量]* - 1`.无需记住冒号,`.ix`,`.loc`,`iloc`,引用字段名称,也不需要在更新原始文件时更新副本. (6认同)
  • 为什么你收到错误的真正问题不是你的代码有什么问题:你可以使用 iloc、loc 或 apply。您遇到的真正问题是由于您创建 df DataFrame 的方式所致。最有可能的是,您将 df 创建为另一个 DataFrame 的切片,而不使用 ``.copy()。``` 将 df 创建为另一个 DataFrame 的切片的正确方法是 ```df = original_df.loc[some slicing ].copy()```。 (5认同)
  • 这会在 Pandas 0.18.0 中引发 SettingWithCopyWarning。 (2认同)

DJK*_*DJK 38

注意:对于使用pandas 0.20.3及更高版本的用户,并且正在寻找答案,所有这些选项都可以使用:

df = pd.DataFrame(np.ones((5,6)),columns=['one','two','three',
                                       'four','five','six'])
df.one *=5
df.two = df.two*5
df.three = df.three.multiply(5)
df['four'] = df['four']*5
df.loc[:, 'five'] *=5
df.iloc[:, 5] = df.iloc[:, 5]*5
Run Code Online (Sandbox Code Playgroud)

结果

   one  two  three  four  five  six
0  5.0  5.0    5.0   5.0   5.0  5.0
1  5.0  5.0    5.0   5.0   5.0  5.0
2  5.0  5.0    5.0   5.0   5.0  5.0
3  5.0  5.0    5.0   5.0   5.0  5.0
4  5.0  5.0    5.0   5.0   5.0  5.0
Run Code Online (Sandbox Code Playgroud)


Sar*_*rah 13

为什么会出现错误的真正问题不在于您的代码有什么问题:您可以使用iloc, loc, or apply, or *=,其中另一个可以工作。

您遇到的真正问题在于您如何创建 df DataFrame。很可能您将 df 创建为另一个 DataFrame 的一个切片,而没有使用.copy(). 将 df 创建为另一个 DataFrame 的一个切片的正确方法是df = original_df.loc[some slicing].copy().

该问题已在您收到的错误消息中说明:“ SettingWithCopyWarning: 正在尝试在 DataFrame 的切片副本上设置值。尝试使用 .loc[row_indexer,col_indexer] = value 代替”
您将收到相同的消息在最新版本的熊猫中也是如此。

每当您收到此类错误消息时,您应该始终检查您创建 DataFrame 的方式。你可能忘记了.copy()

  • 现在这应该是公认的答案。在之前的切片操作中添加.copy()是防止上述警告的关键。 (4认同)

ste*_*enb 8

较新的熊猫版本具有pd.DataFrame.multiply函数。

df['quantity'] = df['quantity'].multiply(-1)
Run Code Online (Sandbox Code Playgroud)


Gia*_*nou 5

尝试df['quantity'] = df['quantity'] * -1


Rgl*_*ish 5

有点旧,但我仍然得到相同的 SettingWithCopyWarning。这是我的解决方案:

df.loc[:, 'quantity'] = df['quantity'] * -1
Run Code Online (Sandbox Code Playgroud)