python-3.x - 这个示例数据清理代码是否更新了 pandas 数据框?
问题描述
在这篇关于使用线性回归预测值的文章中,有一个清理步骤
# For beginning, transform train['FullDescription'] to lowercase using text.lower()
train['FullDescription'].str.lower()
# Then replace everything except the letters and numbers in the spaces.
# it will facilitate the further division of the text into words.
train['FullDescription'].replace('[^a-zA-Z0-9]', ' ', regex = True)
这实际上并不是将更改分配给数据框,是吗?但如果我尝试这样的事情......
train['FullDescription'] = train['FullDescription'].str.lower()
train['FullDescription'] = train['FullDescription'].replace('[^a-zA-Z0-9]', ' ', regex = True)
然后我收到警告...
SettingWithCopyWarning:试图在 DataFrame 中的切片副本上设置值
请参阅文档中的注意事项:http: //pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
应用这些转换的正确方法是什么?它们实际上已经被应用了吗?Aprint(train['FullDescription'])
似乎告诉我他们不是。
编辑:@EdChum 和@jezrael 非常关注缺少代码的问题。当我真正尝试运行它时,我的数据需要分成测试集和训练集。
from sklearn.model_selection import train_test_split
all_data = pandas.read_csv('salary.csv')
train, test = train_test_split(all_data, test_size=0.1)
这似乎是导致此错误的原因。如果我做下一行
train = train.copy()
test = test.copy()
那么一切都很幸福。
您可能想知道我是否不应该只将此步骤应用于all_data
,它可以工作,但是在代码中降低train['Body'].fillna('nan', inplace=True)
仍然会导致错误。因此,问题似乎确实在于train_test_split
不创建副本。
解决方案
应用这些转换的正确方法是......
df.loc[:, 'FullDescription'] = ...
更多关于这方面的信息将在这里。这是 pandas 文档中的一页,一直到底部。引用...
def do_something(df):
foo = df[['bar', 'baz']] # Is foo a view? A copy? Nobody knows!
# ... many lines here ...
# We don't know whether this will modify df or not!
foo['quux'] = value
return foo
您还可以在此处找到为什么要使用.loc
的额外原因。长话短说:显式优于隐式。虽然df['some_column']
没有立即清楚意图,但使用df.loc['some_column']
is。
我真的不知道如何用简单的方式来解释它,但是如果您还有其他问题,或者您认为我可以使我的回答更加明确/雄辩,请告诉我。:)