这个问题是我发布的上一个问题的另一个问题。我想要做的是将DataFrame的字符串值替换为其第一个初始字符串。例如,
s = pd.DataFrame({'A':['S12','S1','E53',np.NaN], 'B':[1,2,3,4]})
s.A.fillna('P', inplace=True)
这将给我一个Dataframe
A B
0 S12 1
1 S1 2
2 E53 3
3 P 4
但是,我想将列'A'的字符串值更改为['S','S','E','P'],这是他们的第一个字符。我做的是跟随,
for i, row in s.iterrows():
if len(row['A']) > 1:
s['A'][i] = row['A'][0]
我收到了这个警告
/anaconda/lib/python2.7/site-packages/ipykernel/__main__.py:3: 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
app.launch_new_instance()
/anaconda/lib/python2.7/site-packages/ipykernel/__main__.py:7: 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
我知道这是一种非首选的方式,但我究竟做得到的效率低,哪种方式更受欢迎?是否可以在不将它们转换为numpy数组的情况下完成?
谢谢!
您可以通过fillna
使用indexing with str和str[0]
:
s['A'] = s['A'].fillna('P').str[0]
print (s)
A B
0 S 1
1 S 2
2 E 3
3 P 4
您可以使用apply方法修剪每行中的文本。也没有得到SettingWithCopyWarning:
警告你必须使用.loc
和copy()
s = s.copy()
s.loc[:,"A"] = s.A.apply(lambda x : x[0])
print(s)
A B
0 S 1
1 S 2
2 E 3
3 P 4
您正在获取“SettingwithCopyWarning”,因为您分配回数据框的方式。如果您希望使用“非首选”方式,则可以使用.loc
来避免此警告消息:
for i, row in s.iterrows():
if len(row['A']) > 1:
s.loc[i,'A'] = row['A'][0]
输出:
A B
0 S 1
1 S 2
2 E 3
3 P 4
注意:您可以在Pandas docs here中获得有关索引链的更多信息。此外,'SettingWithCopyWarning'上有一些好的SO帖子。