【问题标题】:pandas standalone series and from dataframe different behavior熊猫独立系列和来自数据框的不同行为
【发布时间】:2017-01-05 00:05:59
【问题描述】:

这是我的代码和警告信息。如果我通过使用s = pd.Series(np.random.randn(5))s 更改为独立的Series,则不会出现此类错误。在 Windows 上使用 Python 2.7。

似乎从独立创建的系列和从数据框的列创建的系列是不同的行为?谢谢。

我的目的是更改 Series 值本身,而不是更改副本。

源代码

import pandas as pd

sample = pd.read_csv('123.csv', header=None, skiprows=1,
       dtype={0:str, 1:str, 2:str, 3:float})
sample.columns = pd.Index(data=['c_a', 'c_b', 'c_c', 'c_d'])
sample['c_d'] = sample['c_d'].astype('int64')
s = sample['c_d']
#s = pd.Series(np.random.randn(5))
for i in range(len(s)):
    if s.iloc[i] > 0:
        s.iloc[i] = s.iloc[i] + 1
    else:
        s.iloc[i] = s.iloc[i] - 1

警告信息

C:\Python27\lib\site-packages\pandas\core\indexing.py:132: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)

123.csv的内容

c_a,c_b,c_c,c_d
hello,python,numpy,0.0
hi,python,pandas,1.0
ho,c++,vector,0.0
ho,c++,std,1.0
go,c++,std,0.0

编辑1,好像lambda解决方案不起作用,尝试在前后打印s,相同的值,

import pandas as pd

sample = pd.read_csv('123.csv', header=None, skiprows=1,
       dtype={0:str, 1:str, 2:str, 3:float})
sample.columns = pd.Index(data=['c_a', 'c_b', 'c_c', 'c_d'])
sample['c_d'] = sample['c_d'].astype('int64')
s = sample['c_d']
print s
s.apply(lambda x:x+1 if x>0 else x-1)
print s

0    0
1    1
2    0
3    1
4    0
Name: c_d, dtype: int64
Backend TkAgg is interactive backend. Turning interactive mode on.
0    0
1    1
2    0
3    1
4    0

问候, 林

【问题讨论】:

    标签: python python-2.7 pandas numpy dataframe


    【解决方案1】:

    通过执行s = sample['c_d'],如果您更改了s 的值,那么您的原始数据框sample 也会更改。这就是你收到警告的原因。

    您可以改为使用s = sample[c_d].copy(),这样更改s 的值不会更改Dataframe samplec_d 列的值。

    【讨论】:

    • 感谢 iparjono,投票。我可能读错了您的消息,这是我收到的警告消息-“试图在 DataFrame 的切片副本上设置值”,我认为这意味着我正在更改列 c_d 的副本,正确的?但是您提到,我正在更改数据框本身-“如果您更改 s 的值,那么您的样本也会更改。这就是您收到警告的原因”?有点困惑,如果你能澄清一下,那就太好了。 :)
    • 我也可能对这条消息感到困惑。但是,执行 s = sample[c_d]s = sample[c_d].copy 会对您的原始 Dataframe sample 产生不同的影响。
    • 我明白了你的想法,感谢 iparjono 耐心地向我解释。将您的回复标记为答案。
    【解决方案2】:

    我建议你改用 apply 函数:

    s.apply(lambda x:x+1 if x>0 else x-1)
    

    【讨论】:

    • 感谢 Shahram,与使用数据框的列作为系列相比,如果我使用独立系列,您如何解释我的代码没有警告?
    • 顺便说一句,Shahram,您的代码似乎无法按预期工作,请参阅我的试用版编辑 1 部分。谢谢。
    • 消息来了,因为您将 Series 的值更改为 Dataframe 列的副本。当然你没有得到独立系列。
    • @iparjono,感谢您的确认,所以该消息意味着我更改了 Series s(其中s = sample['c_d'])的值,而不是数据框列c_d,因为s 是已经是数据框列c_d 的副本,对吗?
    猜你喜欢
    • 2015-06-23
    • 2022-11-16
    • 1970-01-01
    • 2019-12-13
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多