我有以下索引的DataFrame与命名列和行不连续数字:
a b c d
2 0.671399 0.101208 -0.181532 0.241273
3 0.446172 -0.243316 0.051767 1.577318
5 0.614758 0.075793 -0.451460 -0.012493
Run Code Online (Sandbox Code Playgroud)
我想'e'
在现有数据框中添加一个新列,并且不希望更改数据框中的任何内容(即,新列始终与DataFrame具有相同的长度).
0 -0.335485
1 -1.166658
2 -0.385571
dtype: float64
Run Code Online (Sandbox Code Playgroud)
我尝试了不同的版本join
,append
,merge
,但我没有得到我想要的结果,只在最错误.如何e
在上面的示例中添加列?
我刚刚将我的Pandas从0.11升级到0.13.0rc1.现在,该应用程序正在弹出许多新的警告.其中一个是这样的:
E:\FinReporter\FM_EXT.py:449: SettingWithCopyWarning: 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
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
Run Code Online (Sandbox Code Playgroud)
我想知道究竟是什么意思?我需要改变什么吗?
如果我坚持使用,我应该如何暂停警告quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
?
def _decode_stock_quote(list_of_150_stk_str):
"""decode the webpage and return dataframe"""
from cStringIO import StringIO
str_of_all = "".join(list_of_150_stk_str)
quote_df = pd.read_csv(StringIO(str_of_all), sep=',', names=list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg')) #dtype={'A': object, 'B': object, 'C': np.float64}
quote_df.rename(columns={'A':'STK', 'B':'TOpen', 'C':'TPCLOSE', 'D':'TPrice', 'E':'THigh', 'F':'TLow', 'I':'TVol', 'J':'TAmt', 'e':'TDate', 'f':'TTime'}, inplace=True)
quote_df = quote_df.ix[:,[0,3,2,1,4,5,8,9,30,31]]
quote_df['TClose'] = quote_df['TPrice']
quote_df['RT'] …
Run Code Online (Sandbox Code Playgroud) 我有一个包含4列的pandas DataFrame,我想创建一个只有三列的新 DataFrame .这个问题类似于:从数据框中提取特定列,但是对于不是R的pandas.以下代码不起作用,引发错误,并且当然不是这种方式的pandasnic方法.
import pandas as pd
old = pd.DataFrame({'A' : [4,5], 'B' : [10,20], 'C' : [100,50], 'D' : [-30,-50]})
new = pd.DataFrame(zip(old.A, old.C, old.D)) # raises TypeError: data argument can't be an iterator
Run Code Online (Sandbox Code Playgroud)
什么是pandasnic方式呢?
从父数据帧中选择子数据帧时,我注意到一些程序员使用该.copy()
方法复制数据帧.
他们为什么要复制数据框?如果我不复制会怎么样?
我对Pandas在决定数据帧中的选择是原始数据帧的副本还是原始数据的视图时使用的规则感到困惑.
如果我有,例如,
df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))
Run Code Online (Sandbox Code Playgroud)
我明白a query
返回一个副本,就像这样
foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40
Run Code Online (Sandbox Code Playgroud)
对原始数据帧没有影响df
.我也理解标量或命名切片返回一个视图,以便分配给这些,例如
df.iloc[3] = 70
Run Code Online (Sandbox Code Playgroud)
要么
df.ix[1,'B':'E'] = 222
Run Code Online (Sandbox Code Playgroud)
会改变df
.但是当谈到更复杂的案件时,我迷失了方向.例如,
df[df.C <= df.B] = 7654321
Run Code Online (Sandbox Code Playgroud)
变化df
,但是
df[df.C <= df.B].ix[:,'B':'E']
Run Code Online (Sandbox Code Playgroud)
才不是.
是否有一个简单的规则,熊猫正在使用,我只是缺少?在这些特定情况下发生了什么; 特别是,如何更改满足特定查询的数据帧中的所有值(或值的子集)(正如我在上一个示例中尝试做的那样)?
注意:这与此问题不同 ; 我已经阅读了文档,但没有得到它的启发.我还阅读了关于这个主题的"相关"问题,但我仍然缺少Pandas正在使用的简单规则,以及我如何应用它 - 例如 - 修改值(或值的子集)在满足特定查询的数据框中.
如何将数据帧的给定列的每个元素与标量相乘?(我试过看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 …
Run Code Online (Sandbox Code Playgroud) 我有一个pandas数据帧:数据.它有列["名称","A","B"]
我想做(和工作)的是:
d2 = data[data['name'] == 'fred'] #This gives me multiple rows
d2['A'] = 0
Run Code Online (Sandbox Code Playgroud)
这会将fred行上的A列设置为0.我也做了:
indexes = d2.index
data['A'][indexes] = 0
Run Code Online (Sandbox Code Playgroud)
但是,两人都给了我同样的警告:
/Users/brianp/work/cyan/venv/lib/python2.7/site-packages/pandas/core/indexing.py:128: 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
Run Code Online (Sandbox Code Playgroud)
大熊猫是怎么想让我这样做的?
我喜欢熊猫,并且已经使用它多年并且非常自信我能够很好地处理如何对数据帧进行子集并适当地处理视图与副本(尽管我使用了大量的断言来确定).我也知道有很多关于SettingWithCopyWarning的问题,例如如何处理Pandas中的SettingWithCopyWarning? 以及一些最新的指南,当它发生时缠绕你的头,例如在熊猫中理解SettingWithCopyWarning.
但是我也知道具体的事情,例如这个答案的引用不再出现在最近的文档(0.22.0
)中,并且许多事情已经被多年来弃用(导致一些不合适的旧的SO答案),并且事情正在继续改变.
最近,在教导大熊猫完成新手的基本常规Python知识,例如避免链式索引(和使用.iloc
/ .loc
)之后,我仍然很难提供一般的经验法则来了解何时注意SettingWithCopyWarning
(例如何时重要)忽略它是安全的).
我个人发现根据一些规则(例如切片或布尔运算)对数据帧进行子集化的特定模式,然后修改该子集,与原始数据帧无关,是比文档建议的更常见的操作.在这种情况下,我们希望修改副本而不是原始副本,并且警告对新手来说是混乱/可怕的.
我知道提前查看视图与副本的关系
并不容易,例如Pandas用来生成视图与副本的规则是什么?
在Pandas中检查数据框是复制还是查看
因此,我正在寻找一个更普遍(初学者友好)问题的答案:何时对子集化数据帧执行操作会影响创建它的原始数据帧,以及它们何时独立?.
我已经在下面创建了一些我认为合理的案例,但我不确定是否存在"陷阱"我是否缺失或是否有更简单的方法来思考/检查这一点.我希望有人可以证实我对以下用例的直觉是正确的,因为它与我上面的问题有关.
import pandas as pd
df1 = pd.DataFrame({'A':[2,4,6,8,10],'B':[1,3,5,7,9],'C':[10,20,30,40,50]})
Run Code Online (Sandbox Code Playgroud)
1)警告:无
原始更改:否
# df1 will be unaffected because we use .copy() method explicitly
df2 = df1.copy()
#
# Reference: docs
df2.iloc[0,1] = 100
Run Code Online (Sandbox Code Playgroud)
2)警告:是(我真的不明白为什么)
原来改变了:没有
# df1 will be unaffected because .query() always returns a copy
#
# …
Run Code Online (Sandbox Code Playgroud) 有没有一种简单的方法可以检查两个数据框是不同的副本还是不涉及操作的相同基础数据的视图?我试图抓住每一个生成的时间,并且考虑到规则似乎有多特殊,我想要一种简单的测试方法.
例如,我认为"id(df.values)"在各个视图中都是稳定的,但它们似乎不是:
# Make two data frames that are views of same data.
df = pd.DataFrame([[1,2,3,4],[5,6,7,8]], index = ['row1','row2'],
columns = ['a','b','c','d'])
df2 = df.iloc[0:2,:]
# Demonstrate they are views:
df.iloc[0,0] = 99
df2.iloc[0,0]
Out[70]: 99
# Now try and compare the id on values attribute
# Different despite being views!
id(df.values)
Out[71]: 4753564496
id(df2.values)
Out[72]: 4753603728
# And we can of course compare df and df2
df is df2
Out[73]: False
Run Code Online (Sandbox Code Playgroud)
其他答案我已经抬头试图给出规则,但似乎不一致,也不回答如何测试的问题:
当然: - http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy …
关于可怕的问题,有无数的问题 SettingWithCopyWarning
我已经很好地理解了它是如何产生的.(注意我说好,不好)
当数据df
帧通过存储的属性"附加"到另一个数据帧时,就会发生这种情况is_copy
.
这是一个例子
df = pd.DataFrame([[1]])
d1 = df[:]
d1.is_copy
<weakref at 0x1115a4188; to 'DataFrame' at 0x1119bb0f0>
Run Code Online (Sandbox Code Playgroud)
我们可以将该属性设置为None
或
d1 = d1.copy()
Run Code Online (Sandbox Code Playgroud)
我见过像@Jeff这样的开发者,我不记得还有谁,警告这样做.引用SettingWithCopyWarning
有目的.
问题
好的,那么什么是一个具体的例子,说明为什么通过分配copy
回原始来忽略警告是一个坏主意.
我会定义"坏主意"以澄清.
坏主意
这是一个坏主意来放置代码投入生产,这将导致越来越在星期六晚上说你的代码被打破,需要固定的中间一个电话.
现在如何使用df = df.copy()
以绕过SettingWithCopyWarning
导致获得那种电话.我想要它拼写出来,因为这是一个混乱的来源,我试图找到清晰度.我想看到爆炸的边缘情况!