Python 2.7 避免链式选择
我正在尝试确定“最佳实践”来执行以下操作,而不会导致设置CopyWarning。我正在使用python 2.7和pandas 15.2 我想做的是再选择一个数据帧,然后将此选择用作新的数据帧,而不冒修改原始数据帧的风险。下面是我正在做的一个例子:Python 2.7 避免链式选择,python-2.7,pandas,Python 2.7,Pandas,我正在尝试确定“最佳实践”来执行以下操作,而不会导致设置CopyWarning。我正在使用python 2.7和pandas 15.2 我想做的是再选择一个数据帧,然后将此选择用作新的数据帧,而不冒修改原始数据帧的风险。下面是我正在做的一个例子: import pandas as pd def select_blue_cars(df): """Returns a new dataframe of blue cars""" return df[df['color'] == 'bl
import pandas as pd
def select_blue_cars(df):
"""Returns a new dataframe of blue cars"""
return df[df['color'] == 'blue']
cars = pd.DataFrame({'color': ['blue', 'blue', 'red'], 'make': ['Ford', 'BMW', 'Ford']})
blue_cars = select_blue_cars(cars)
blue_cars['price'] = 10000
上述操作在当前pandas中生成了一个带有CopyWarning的设置,但其行为与我所希望的一样(即cars
df未被修改)
- 执行
选择_blue_cars
以使后续代码不会触发此警告的最佳方法是什么
- 我应该到处使用
.copy()
吗
return df[df['color'] == 'blue'].copy()
- (旁白)
copy()
的性能怎么样李>
最后,我想链接一些简单的转换函数,如选择\u blue\u cars
:
blue_fords = select_fords(select_blue_cars(cars))
Edit:仔细考虑后,我认为我正在寻找一种转换,它从数据帧中选择一个副本,而不显式调用.copy()
。这样我就可以编写函数对df进行小的转换并将它们链接起来
例如,转置df.T
给出了一个新的数据帧。无需调用.copy()
看起来,在选择的情况下,这个模式需要.copy()
。我认为这仍然是熊猫比较容易混淆的部分之一。你实际上问了两三个问题,答案可能没有你想象的那么简单。因此,我将做一个简化的假设,即将所有内容都保存在一个数据集中(如果不是,那也没什么大不了的),并给出一个简单的答案
要执行的操作(伪代码):
price=10000如果颜色==蓝色
最简单的方法实际上是使用numpywhere()
:
cars['price']=np.where(cars['color']='blue',10000,np.nan)
您还可以嵌套where()
,因此对于这样的条件设置,它确实是非常强大和简单的方法。您还可以使用ix/loc/iloc
(尽管您需要先为“price”创建一个空列):
cars.ix[cars.color='blue','price']=10000
为了简要说明链式索引警告,它主要说的是,在设置值时,不要尝试在左侧做太多操作:
df[df.y>5]['x']=df['z']
不过这没关系:
df['x']=df[df.y>5]['z']
因为链式索引的结果可能是通过副本而不是引用,这将导致前者失败,而不是后者失败。您也可以通过使用ix/loc/iloc
绕过设置CopyWarning
取决于您计划保留子集的时间。如果您只想简单地看一下特定颜色内的价格,然后返回到整体数据框,那么JohnE给出的建议非常好。如果您确实希望保留子集并对其执行一系列单独的分析,那么我通常使用.loc
进行子集并显式复制,例如:
subset = df.loc[df['condition'] > 5, :].copy()
在您的代码中,这将是:
import pandas as pd
def select_blue_cars(df):
"""Returns a new dataframe of blue cars"""
return df.loc[df['color'] == 'blue', :].copy()
cars = pd.DataFrame({'color': ['blue', 'blue', 'red'], 'make': ['Ford', 'BMW', 'Ford']})
blue_cars = select_blue_cars(cars)
blue_cars['price'] = 10000
settingwithcopywarning用于提醒您可能正在修改数据帧的副本。这是来自蓝车['price']=10000行的警告吗?你应该试着用blue_cars.loc代替。如果这是您明确的意图,那么警告只是建议您函数可能没有按照您的想法执行。我只是尝试了您的代码,没有得到警告。到底是哪一行?这是我在JohnE设定价格的最后一行。熊猫的版本很重要。我在15.3收到警告。我想我需要做的就是希望有人能纠正我!调用两个方法来执行此操作感觉有些不对劲。在我的编辑中,cars.T
或类似的转换不需要在上面加上.copy()
。感谢您的回答。最终将使用.copy()而不是实际复制两次?您的回答很有帮助,因为它表明我可能无法使用单个数据帧方法来完成我想要的任务。在这种情况下,我不想修改原始数据帧,我想选择它的一部分并独立使用它。现在可能更重要的一点是熊猫不应该以这种方式使用,我应该重构东西,这样我就可以修改单个数据帧了!
subset = df.loc[df['condition'] > 5, :].copy()
import pandas as pd
def select_blue_cars(df):
"""Returns a new dataframe of blue cars"""
return df.loc[df['color'] == 'blue', :].copy()
cars = pd.DataFrame({'color': ['blue', 'blue', 'red'], 'make': ['Ford', 'BMW', 'Ford']})
blue_cars = select_blue_cars(cars)
blue_cars['price'] = 10000