【问题标题】:Set value to an entire column of a pandas dataframe将值设置为 pandas 数据框的整列
【发布时间】:2017-06-23 13:54:43
【问题描述】:

我正在尝试将数据框的整个列设置为特定值。

In  [1]: df
Out [1]: 
     issueid   industry
0        001        xxx
1        002        xxx
2        003        xxx
3        004        xxx
4        005        xxx

据我所知,loc 是替换数据框中的值时的最佳做法(或者不是吗?):

In  [2]: df.loc[:,'industry'] = 'yyy'

但是,我仍然收到了这条备受关注的警告信息:

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

如果我这样做

In  [3]: df['industry'] = 'yyy'

我收到了同样的警告信息。

有什么想法吗?使用 Python 3.5.2 和 pandas 0.18.1。

【问题讨论】:

  • 您必须在致电df.loc[:,'industry']='yyy' 之前对df 进行了操作,因为您发布的内容应该有效。基本上,如果您拍摄了未显示的起始 df 的切片或子部分,则会引发警告

标签: python pandas dataframe


【解决方案1】:

你可以使用assign函数:

df = df.assign(industry='yyy')

【讨论】:

  • 这个方法对我有用,没有给我警告。
  • 这应该是答案。一个好的答案对每个人都有用。不只是提出问题的人。
  • 如何将这种方法与多索引一起使用?
  • 这没有引发警告。
【解决方案2】:

当从现有对象定义新对象时,Python 可能会做出意想不到的事情。您在上面的评论中声明您的数据框是按照df = df_all.loc[df_all['issueid']==specific_id,:] 定义的。在这种情况下,df 实际上只是存储在 df_all 对象中的行的替代:不会在内存中创建新对象。

为了完全避免这些问题,我经常不得不提醒自己使用copy 模块,它显式地强制将对象复制到内存中,以便对新对象调用的方法不会应用于源对象。我和你有同样的问题,并使用deepcopy 函数避免了它。

在您的情况下,这应该消除警告消息:

from copy import deepcopy
df = deepcopy(df_all.loc[df_all['issueid']==specific_id,:])
df['industry'] = 'yyy'

编辑:另请参阅下面 David M. 的出色评论!

df = df_all.loc[df_all['issueid']==specific_id,:].copy()
df['industry'] = 'yyy'

【讨论】:

  • 这可以(我认为)不用copy 模块也可以通过使用Pandas copy 函数来完成(例如 df=df_all.loc[df_call['issueid']==specific_id,:].copy()
【解决方案3】:
df.loc[:,'industry'] = 'yyy'

这很神奇。您将为所有行添加 '.loc' 和 ':'。希望对你有帮助

【讨论】:

  • 这仍然会引发“SettingwithaCopy”警告。
【解决方案4】:

你可以这样做:

df['industry'] = 'yyy'

【讨论】:

  • 还是同样的警告信息。
  • 你的数据框是如何构建的?因为我在使用随机数据帧时没有这个警告。
  • df 取自更广泛的数据框 df_all。类似于 df = df_all.loc[df_all['issueid']==specific_id,:]。我想你已经明白了,因为当我执行 df_all['industry']='yyy' 时,我没有看到这条消息。但我不知道为什么 df 不是“正常”数据框。
  • 这是你的 df = df_all.loc[df_all['issueid']==specific_id,:] ;尝试改用 df = df_all[df_all['issueid']==specific_id]
  • 是的,明白了。想解释一下两者之间的区别是什么?是不是跟“副本”有关系?
【解决方案5】:

假设您的数据框类似于“数据”,您必须考虑您的数据是字符串还是整数。两者的待遇不同。所以在这种情况下,您需要具体说明这一点。

import pandas as pd

data = [('001','xxx'), ('002','xxx'), ('003','xxx'), ('004','xxx'), ('005','xxx')]

df = pd.DataFrame(data,columns=['issueid', 'industry'])

print("Old DataFrame")
print(df)

df.loc[:,'industry'] = str('yyy')

print("New DataFrame")
print(df)

现在如果要输入数字而不是字母,您必须创建和排列

list_of_ones = [1,1,1,1,1]
df.loc[:,'industry'] = list_of_ones
print(df)

或者如果你使用的是 Numpy

import numpy as np
n = len(df)
df.loc[:,'industry'] = np.ones(n)
print(df)

【讨论】:

    【解决方案6】:

    这使您可以在行上添加条件,然后更改与这些行对应的特定列的所有单元格:

    df.loc[(df['issueid'] == '001'), 'industry'] = str('yyy')
    

    【讨论】:

      【解决方案7】:

      在我看来:

      df1 = df[df['col1']==some_value] 不会创建一个新的DataFrame,基本上,df1的变化会反映在父df中。这会导致警告。 然而, df1 = df[df['col1]]==some_value].copy() WILL 创建一个新的DataFrame,df1的变化不会反映在df中。如果您不想更改原始 df,建议使用 copy() 方法。

      【讨论】:

        【解决方案8】:

        在使用这种方法df.loc[:,'industry'] = 'yyy' 之前我也遇到过类似的问题,但是一旦我刷新了笔记本,它就运行良好。

        您可能想在拥有df.loc[:,'industry'] = 'yyy' 后尝试刷新单元格。

        【讨论】:

          【解决方案9】:

          如果您只是创建新的但为空的数据框,则不能直接将值签名到整列。这将显示为 NaN,因为系统不知道数据框将有多少行!您需要定义大小或有一些现有的列。

          df = pd.DataFrame()
          df["A"] = 1
          df["B"] = 2
          df["C"] = 3
          

          【讨论】:

            猜你喜欢
            • 2016-09-01
            • 1970-01-01
            • 2022-12-09
            • 2019-05-03
            • 2016-12-05
            • 2018-12-17
            • 1970-01-01
            • 2019-01-15
            • 1970-01-01
            相关资源
            最近更新 更多