pandas.read_csv中的dtype和converters有什么区别?

40

pandas函数read_csv()用于读取.csv文件。其文档在这里

根据文档,我们知道:

dtype:数据类型或列名称与类型的字典,默认为None。用于数据或列的数据类型。例如 {‘a’: np.float64, ‘b’: np.int32}(不支持engine=’python’)。

converters:字典,默认为None。用于转换某些列中值的函数的字典。键可以是整数或列标签。

使用此函数时,可以调用pandas.read_csv('file', dtype=object)pandas.read_csv('file', converters=object)其中,converter的名字说明了数据类型将被转换,但我想知道dtype的情况如何?

3个回答

35

语义上的区别在于 dtype 允许你指定如何处理值,例如,将其视为数字或字符串类型。

转换器允许您解析输入数据并使用转换函数将其转换为所需的 dtype,例如,将字符串值解析为日期时间或其他所需的 dtype。

在这里,我们看到 pandas 尝试嗅探类型:

In [2]:
df = pd.read_csv(io.StringIO(t))
t="""int,float,date,str
001,3.31,2015/01/01,005"""
df = pd.read_csv(io.StringIO(t))
df.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1 entries, 0 to 0
Data columns (total 4 columns):
int      1 non-null int64
float    1 non-null float64
date     1 non-null object
str      1 non-null int64
dtypes: float64(1), int64(2), object(1)
memory usage: 40.0+ bytes

你可以从上面看到,001005被视为int64,但日期字符串保持为str
如果我们说一切都是object,那么本质上一切都是str
In [3]:    
df = pd.read_csv(io.StringIO(t), dtype=object).info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1 entries, 0 to 0
Data columns (total 4 columns):
int      1 non-null object
float    1 non-null object
date     1 non-null object
str      1 non-null object
dtypes: object(4)
memory usage: 40.0+ bytes

在这里,我们强制将 int 列转换为 str,并告诉 parse_dates 使用 date_parser 来解析日期列:

In [6]:
pd.read_csv(io.StringIO(t), dtype={'int':'object'}, parse_dates=['date']).info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1 entries, 0 to 0
Data columns (total 4 columns):
int      1 non-null object
float    1 non-null float64
date     1 non-null datetime64[ns]
str      1 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(1), object(1)
memory usage: 40.0+ bytes

同样地,我们可以传递 to_datetime 函数来转换日期:
In [5]:
pd.read_csv(io.StringIO(t), converters={'date':pd.to_datetime}).info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 1 entries, 0 to 0
Data columns (total 4 columns):
int      1 non-null int64
float    1 non-null float64
date     1 non-null datetime64[ns]
str      1 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(2)
memory usage: 40.0 bytes

我应该指出,对于其他人来说,两个参数都可以在同一次“read_csv”调用中提供,尽管我没有测试在使用该API时同时引用了“dtypes”和“converters”字典中重叠的列。 - jxramos
有没有办法制作自己的嗅探器来转换数据类型?我觉得这在拥有许多列的 Excel 文件中会非常有用。 - Maxim
那行不通,Excel表格是使用第三方模块导入的,因此数据类型是通过该模块提供的。如果它是CSV文件,那么您可以定义自己的函数并将其加载到转换器中,并将其应用于每一列,这样就可以实现。 - EdChum
1
回复 @jxramos 的评论,至少在 pandas 1.3.1 中,“转换器”优先于“数据类型”,如果同一列在两个参数中都被引用。 - Lionel Hamayon

8
我认为转换器的主要目的是操作列的值,而不是数据类型。@EdChum分享的答案侧重于dtypes的概念。它使用pd.to_datetime函数。
在这篇文章https://medium.com/analytics-vidhya/make-the-most-out-of-your-pandas-read-csv-1531c71893b5中关于转换器的部分,你会看到一个例子,将csv列中的"185 lbs."等值更改为从文本列中删除"lbs"的内容。这更符合read_csvconverters参数的思想。

.csv文件长什么样子(如果图片未显示,请进入文章查看。)
带有6列的csv文件。重量是一个包含145磅等条目的列。

#creating functions to clean the columns
w = lambda x: (x.replace('lbs.',''))
r = lambda x: (x.replace('"',''))
#using converters to apply the functions to the columns
fighter = pd.read_csv('raw_fighter_details.csv' , 
                      converters={'Weight':w , 'Reach':r }, 
                      header=0, 
                      usecols = [0,1,2,3])
fighter.head(15)

使用converters转换Weight列后的DataFrame
在此输入图片描述

请注意,r lambda函数是用于Reach列而不是Height列的。 - VISQL

0

我们使用转换器来更改特定单元格的值。

我们可以在转换器中为特定列编写函数,并且它将运行该列中的每个单元格。

请参见下面的示例,这是一个数据框,我们正在尝试更改那些突出显示的值

输入图像描述

   import pandas as pd
def converst_peopple_cell(cell):
  if cell=='n.a.':
    return 'Sam Walton'
  else:
    return cell       # if the cell value is not 'n.a.' then it will return the orginal value of the cell
def convert_eps_cell(cell):
  if cell=='not available':
    return None
  else:
    return cell
df=pd.read_csv('https://raw.githubusercontent.com/codebasics/py/master/pandas/4_read_write_to_excel/stock_data.csv',converters={
    'people': converst_peopple_cell,
    'eps':convert_eps_cell
   
})
df    

我们使用转换器参数,类似于Python字典,可以选择某些特定列并应用某些特定函数,对于特定的列(如people),它将为该列中的每个单元格调用此函数convert_people_cell。

在对people列使用转换器后的DataFrame:

输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接