【问题标题】:Converting string objects to int/float using pandas使用 pandas 将字符串对象转换为 int/float
【发布时间】:2014-07-25 02:34:54
【问题描述】:
import pandas as pd

path1 = "/home/supertramp/Desktop/100&life_180_data.csv"

mydf =  pd.read_csv(path1)

numcigar = {"Never":0 ,"1-5 Cigarettes/day" :1,"10-20 Cigarettes/day":4}

print mydf['Cigarettes']

mydf['CigarNum'] = mydf['Cigarettes'].apply(numcigar.get).astype(float)

print mydf['CigarNum']

mydf.to_csv('/home/supertramp/Desktop/powerRangers.csv')

csv 文件“100&life_180_data.csv”包含年龄、bmi、香烟、酒精等列。

No                int64
Age               int64
BMI             float64
Alcohol          object
Cigarettes       object
dtype: object

香烟列包含“从不”、“1-5 根香烟/天”、“10-20 根香烟/天”。 我想为这些对象分配权重(从不,1-5 支香烟/天,....)

预期的输出是附加的新列 CigarNum,仅包含数字 0、1、2 CigarNum 与预期一样直到 8 行,然后在 CigarNum 列中显示 Nan 直到最后一行

0                     Never
1                     Never
2        1-5 Cigarettes/day
3                     Never
4                     Never
5                     Never
6                     Never
7                     Never
8                     Never
9                     Never
10                    Never
11                    Never
12     10-20 Cigarettes/day
13       1-5 Cigarettes/day
14                    Never
...
167                    Never
168                    Never
169     10-20 Cigarettes/day
170                    Never
171                    Never
172                    Never
173                    Never
174                    Never
175                    Never
176                    Never
177                    Never
178                    Never
179                    Never
180                    Never
181                    Never
Name: Cigarettes, Length: 182, dtype: object

在前几行之后,我得到的输出不应该给出 NaN。

0      0
1      0
2      1
3      0
4      0
5      0
6      0
7      0
8      0
9      0
10   NaN
11   NaN
12   NaN
13   NaN
14     0
...
167   NaN
168   NaN
169   NaN
170   NaN
171   NaN
172   NaN
173   NaN
174   NaN
175   NaN
176   NaN
177   NaN
178   NaN
179   NaN
180   NaN
181   NaN
Name: CigarNum, Length: 182, dtype: float64

【问题讨论】:

  • 您确定第 10 行和第 11 行实际上等于“从不”并且值中没有空格或其他字符吗?
  • 是的,我直到现在才检查空间。真的谢谢。你能帮我用一种有效的方法来忽略这些空间吗。我有更多的列在开始时有空间。提前致谢.

标签: python csv pandas


【解决方案1】:

好的,第一个问题是你有嵌入的空格导致函数错误地应用:

使用矢量化str 修复此问题:

mydf['Cigarettes'] = mydf['Cigarettes'].str.replace(' ', '')

现在创建您的新列应该可以正常工作了:

mydf['CigarNum'] = mydf['Cigarettes'].apply(numcigar.get).astype(float)

更新

感谢@Jeff 一如既往地指出出色的做事方式:

所以你可以打电话给replace而不是打电话给apply

mydf['CigarNum'] = mydf['Cigarettes'].replace(numcigar)
# now convert the types
mydf['CigarNum'] = mydf['CigarNum'].convert_objects(convert_numeric=True)

你也可以使用factorize方法。

考虑一下为什么不直接将 dict 值设置为浮点数,然后避免类型转换?

所以:

numcigar = {"Never":0.0 ,"1-5 Cigarettes/day" :1.0,"10-20 Cigarettes/day":4.0}

0.17.0 或更新版本

convert_objects0.17.0 以来已弃用,已替换为to_numeric

mydf['CigarNum'] = pd.to_numeric(mydf['CigarNum'], errors='coerce')

这里errors='coerce' 将返回NaN,其中的值无法转换为数值,否则将引发异常

【讨论】:

  • 你可以用series.replace(dict)我相信做替换,然后convert_objects(convert_numeric=True)改成float(强制);您也可以factorize 进行分类(例如将字符串映射到数字)
  • @Jeff 所以replace 比现在调用mapapply 并传递一个dict 快吗?也不知道factorize,这是什么时候引入的?
  • 替换应该快得多; factorize 已经有一段时间了(但没有做广告:))
  • @EdChum 嗨,当我这样做时,我得到“试图在数据帧的切片副本上设置值”如何更改原始数据帧?
  • @h_musk 请参阅stackoverflow.com/questions/20625582/… 基本上如果您想对副本进行操作,则应致电df.copy(),否则如果您想对视图进行操作,请点击该链接
【解决方案2】:

尝试使用此功能解决所有此类问题:

def get_series_ids(x):
    '''Function returns a pandas series consisting of ids, 
       corresponding to objects in input pandas series x
       Example: 
       get_series_ids(pd.Series(['a','a','b','b','c'])) 
       returns Series([0,0,1,1,2], dtype=int)'''

    values = np.unique(x)
    values2nums = dict(zip(values,range(len(values))))
    return x.replace(values2nums)

【讨论】:

  • 太好了!次要 cmets:需要 import numpy as np;所需的附加组件:如果发生这种情况,可以选择为空值分配 -1 或类似的值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 2014-04-03
相关资源
最近更新 更多