Pandas数据帧:将混合类型的字符串值转换为float,同时跟踪真正的字符串值

时间:2018-03-31 20:38:47

标签: python pandas dataframe type-conversion

我从网页上擦洗了一张桌子。 有些列包含美元金额或百分比(作为字符串),但有些条目有一些注释,即'(n)'。 在我将str(数字)转换为float之前,我需要检查注释以确定它们是否应该为0或NA。

我需要的是输出带有注释的每个条目的行和注释,即     (4,'(4)'),(13,'(4)'); #或矢量

使用python:3.5.4;大熊猫:0.22.0

我复制了一个较小的数据帧:

df = pd.DataFrame({'A':[ '$104.64', '$73.04', '(4)', '$82.95', '$92.45', '$95.09', 
                    '$79.20', '$63.66', '$90.27', '$98.80', '$33.82', '(8)', '$56.74', '$49.22', 
                    '$75.74'], 
               'B':['%28.90', '%73.36', '(3)', '%104.64', '%73.04', '%82.95',  
                    '%79.20', '(9)', '%63.66', '%90.27', '%98.80', '%33.82', '%56.74', '%49.22', 
                    '%75.74']})
df

        A   B
0   $104.64 %28.90
1   $73.04  %73.36
2   (4) (3)
3   $82.95  %104.64
4   $92.45  %73.04
5   $95.09  %82.95
6   $79.20  %79.20
7   $63.66  (9)
8   $90.27  %63.66
9   $98.80  %90.27
10  $33.82  %98.80
11  (8) %33.82
12  $56.74  %56.74
13  $49.22  %49.22
14  $75.74  %75.74

out = df['A'].where( df['A']>='(' )   # 1. how to get rid of the NaN?
out

out = out.astype(dtype=str)           # 2. found that NaN is of type float, 
                                           so now all entries are str
out

得到:

2  '(4)'
11 '(8)'

我尝试了这个,但这没有帮助,因为音符值更改为True:

df['A'].where( df['A']>='(' ).isna() == False

0     False
1     False
2      True
3     False
4     False
5     False
6     False
7     False
8     False
9     False
10    False
11     True
12    False
13    False
14    False

我[找到] [Skipping char-string values while comparing to a column values of mixed type to int or float in pandas Dataframe的最接近的答案无济于事:

pd.to_numeric(df.A.str.strip('$'), errors='coerce')

执行转换,但将'(n)'音符值转换为nan。

总结: 由于注释,问题是列中的混合类型: 我不能剥离'$'或'%',然后转换为float。 我还需要记录这些内容。

我可能对一个简单的解决方案视而不见......

2 个答案:

答案 0 :(得分:1)

因为我没有足够的声誉来发表评论...... 你能用df.loc []来提取'('?

withnotes = df.loc[df['A'].str.contains('\(')]
output = [(i, row.A) for i, row in withnotes.iterrows()]
output

上面的示例仅解析列A并返回元组列表:     输出= [(2,'(4)'),(11,'(8)')]

答案 1 :(得分:0)

您可以使用.loc访问者:

res = df.loc[df['A'].str[0] == '(', 'A']

这导致一系列:

2     (4)
11    (8)
Name: A, dtype: object

如果您需要数据框:

res = df.loc[df['A'].str[0] == '(', 'A'].to_frame()