这个问题是我发布的上一个问题的另一个问题。我想要做的是将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数组的情况下完成?
谢谢!
答案 0 :(得分:1)
您可以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
答案 1 :(得分:0)
您可以使用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
答案 2 :(得分:0)
由于您分配回数据框的方式,您正在获取“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文档here中获取有关索引链的更多信息。此外,'SettingWithCopyWarning'上有一些好的SO帖子。