Python pandas 数据框警告,建议改用 .loc 吗?

Posted

技术标签:

【中文标题】Python pandas 数据框警告,建议改用 .loc 吗?【英文标题】:Python pandas data frame warning, suggest to use .loc instead? 【发布时间】:2015-05-29 14:04:48 【问题描述】:

您好,我想通过删除缺失的信息并将所有字母小写来操作数据。但对于小写转换,我收到以下警告:

E:\Program Files Extra\Python27\lib\site-packages\pandas\core\frame.py:1808: UserWarning: Boolean Series key will be reindexed to match DataFrame index.
  "DataFrame index.", UserWarning)
C:\Users\KubiK\Desktop\FamSeach_NameHandling.py:18: 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

请参阅文档中的注意事项:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy frame3["name"] = frame3["name"].str.lower()

C:\Users\KubiK\Desktop\FamSeach_NameHandling.py:19: 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

请参阅文档中的注意事项:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy frame3["ethnicity"] = frame3["ethnicity"].str.lower()

import pandas as pd
from pandas import DataFrame

# Get csv file into data frame
data = pd.read_csv("C:\Users\KubiK\Desktop\OddNames_sampleData.csv")
frame = DataFrame(data)
frame.columns = ["name", "ethnicity"]
name = frame.name
ethnicity = frame.ethnicity

# Remove missing ethnicity data cases
index_missEthnic = frame.ethnicity.isnull()
index_missName = frame.name.isnull()
frame2 = frame[index_missEthnic != True]
frame3 = frame2[index_missName != True]

# Make all letters into lowercase
frame3["name"] = frame3["name"].str.lower()
frame3["ethnicity"] = frame3["ethnicity"].str.lower()

# Test outputs
print frame3

这个警告似乎并不致命(至少对于我的小样本数据而言),但我应该如何处理呢?

样本数据

Name    Ethnicity
Thos C. Martin                              Russian
Charlotte Wing                              English
Frederick A T Byrne                         Canadian
J George Christe                            French
Mary R O'brien                              English
Marie A Savoie-dit Dugas                    English
J-b'te Letourneau                           Scotish
Jane Mc-earthar                             French
Amabil?? Bonneau                            English
Emma Lef??c                                 French
C., Akeefe                                  African
D, James Matheson                           English
Marie An: Thomas                            English
Susan Rrumb;u                               English
                                            English
Kaio Chan   

【问题讨论】:

我很好奇您是否阅读了警告建议的注意事项。他们是如何未能为您回答这个问题的? 我确实阅读了警告。这是一个过于简化的示例,对像我这样的新程序员没有用处。即使我遵循经验丰富的程序员使用 .loc 的建议,同样的警告仍然存在(如下所示)。 在我看来,这个例子与你的非常相似。在下面的答案中,您仍然分配了一个副本——换句话说,loc 在错误的一边。请参阅我对该帖子的评论。 【参考方案1】:

当你设置 frame2/3 时,尝试使用 .loc 如下:

frame2 = frame.loc[~index_missEthnic, :]
frame3 = frame2.loc[~index_missName, :]

我认为这可以解决您看到的错误:

frame3.loc[:, "name"] = frame3.loc[:, "name"].str.lower()
frame3.loc[:, "ethnicity"] = frame3.loc[:, "ethnicity"].str.lower()

您也可以尝试以下方法,尽管它不能回答您的问题:

frame3.loc[:, "name"] = [t.lower() if isinstance(t, str) else t for t in frame3.name]
frame3.loc[:, "ethnicity"] = [t.lower() if isinstance(t, str) else t for t in frame3. ethnicity]

这会将列中的任何字符串转换为小写,否则它会保持该值不变。

【讨论】:

谢谢我按照你的建议做了,但仍然有如下警告信息 C:\Users\KubiK\Desktop\FamSeach_NameHandling.py:18: SettingWithCopyWarning: 试图在数据帧的切片副本上设置值。尝试改用 .loc[row_indexer,col_indexer] = value 请参阅文档中的警告:pandas.pydata.org/pandas-docs/stable/… frame3["name"] = frame3["name"].str.lower() C:\Users\KubiK\Desktop \FamSeach_NameHandling.py:19:SettingWithCopyWarning:试图在数据帧的切片副本上设置值。尝试改用 .loc[row_indexer,col_indexer] = value 查看文档中的注意事项:pandas.pydata.org/pandas-docs/stable/… frame3["ethnicity"] = frame3["ethnicity"].str.lower() @KubiK888:顺便说一句,它有助于提供一些示例数据,以便用户可以使用它(与您计算机上的 csv 文件相比)。 @Alexander 您仍在分配给副本。我认为您应该编辑您的答案以反映我上面的评论,以便未来的读者不必滚动浏览所有这些 cmets。【参考方案2】:

不知道为什么需要这么多布尔值... 另请注意,.isnull() 不会捕获空字符串。 在应用.lower() 之前过滤空字符串似乎也没有必要。 但这是有必要的......这对我有用:

frame = pd.DataFrame('name':['Abc Def', 'EFG GH', ''], 'ethnicity':['Ethnicity1','', 'Ethnicity2'])
print frame

    ethnicity     name
0  Ethnicity1  Abc Def
1               EFG GH
2  Ethnicity2         

name_null = frame.name.str.len() == 0
frame.loc[~name_null, 'name'] = frame.loc[~name_null, 'name'].str.lower()
print frame

    ethnicity     name
0  Ethnicity1  abc def
1               efg gh
2  Ethnicity2         

【讨论】:

以上是关于Python pandas 数据框警告,建议改用 .loc 吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python pandas 数据框时返回副本与视图警告

Python Pandas 多索引名称警告

将 Python Pandas 数据框转换为 JSon 格式并通过使用 Python 添加其列名保存到 MongoDB 数据库中

pandas 将多个数据框合并并更新为一列

Python Pandas 绘图警告

python--pandas分组聚合