Pandas.read_csv类型转换如何工作?

时间:2018-07-27 11:24:16

标签: python pandas

使用带有pandas.read_csv选项的parse_dates和自定义日期解析器,我发现Pandas对读取的数据类型有自己的看法。

csv示例:

"birth_date", "name"
"","Dr. Who"
"1625", "Rembrandt"
"1533", "Michel"

实际的日期清除器是here,但我的工作可以归结为:

import pandas as pd

def dateclean(date):
    return str(int(date)) # Note: we return A STRING

df = pd.read_csv(
        'my.csv', 
        parse_dates=['birth_date'],
        date_parser=dateclean, 
        engine='python'
        )

print(df.birth_date)       

输出:

0       NaN
1    1625.0
2    1533.0
Name: birth_date, dtype: float64

当我指定float64时,得到的类型为str even 。另外,取出CSV中的第一行,其出生日期为空,然后输入int。解决方法很简单:

return '"{}"'.format(int(date))

有更好的方法吗?

在数据分析中,我可以想象熊猫会说“嘿,伙计,您以为您正在阅读字符串,但实际上它们是数字”很有用。但是,当我告诉我拒绝时,否决我的理由是什么?

2 个答案:

答案 0 :(得分:1)

对我来说,使用parse_dates / date_parser看起来有点复杂,除非您想在许多日期列上归纳您的导入。我认为您可以通过converters参数来更好地控制,可以在其中容纳dateclean()函数。您也可以尝试使用dtype参数。

原始dateclean()函数的问题在于,它的""值失败,因为int("")引发了ValueError。遇到此问题时,熊猫似乎会诉诸于标准导入,但是它会因converters而明显失败。

下面是演示修补程序的代码:

import pandas as pd
from pathlib import Path

doc = """"birth_date", "name"
"","Dr. Who"
"1625", "Rembrandt"
"1533", "Michel"
"""

Path('my.csv').write_text(doc)

def dateclean(date):
    try: 
       return str(int(date)) 
    except ValueError:
       return '' 

df = pd.read_csv(
        'my.csv', 
        parse_dates=['birth_date'],
        date_parser=dateclean, 
        engine='python'
        )

df2 = pd.read_csv(
        'my.csv', 
        converters = {'birth_date': dateclean}
        )

print(df2.birth_date)  

希望有帮助。

答案 1 :(得分:1)

问题是date_parser专为转换为datetime而设计:

  

date_parser 函数,默认为None
用于将字符串列序列转换为日期时间数组的函数   实例。

没有理由您应该期望将此参数用于其他类型。而是可以使用converters参数。在这里,我们使用toolz.compose来应用int,然后应用str。或者,您可以使用lambda x: str(int(x))

from io import StringIO
import pandas as pd
from toolz import compose

mystr = StringIO('''"birth_date", "name"
"","Dr. Who"
"1625", "Rembrandt"
"1533", "Michel"''')

df = pd.read_csv(mystr, 
                 converters={'birth_date': compose(str, int)},
                 engine='python')

print(df.birth_date)       

0     NaN
1    1625
2    1533
Name: birth_date, dtype: object

如果您需要用空字符串替换NaN,则可以用fillna进行后处理:

print(df.birth_date.fillna(''))       

0        
1    1625
2    1533
Name: birth_date, dtype: object