【问题标题】:how to preserve dtypes of dataframes when using to_csv?使用 to_csv 时如何保留数据帧的 dtypes?
【发布时间】:2020-10-12 03:31:37
【问题描述】:

为了降低内存成本,我使用 astype() 指定了我的 pandas 数据帧的 dtypes,例如:

df['A'] = df['A'].astype(int8)

然后我使用to_csv()来存储它,但是当我使用read_csv()再次读取它并检查dtypes时,我发现它仍然存储在int64中。 如何在将 dtypes 保存在本地存储中的同时保留它?

【问题讨论】:

  • 您正在写出文本,没有带有文本的 dtypes 的概念,您需要在再次读取 csv 时再次指定 dtypes 参见 read_csv 您需要将参数传递给 @ 987654328@arg
  • @EdChum 现在我明白了。谢谢!

标签: python pandas


【解决方案1】:

这是一个的方法:

import pandas as pd

# Create Example data with types
df = pd.DataFrame({
    'words': ['foo', 'bar', 'spam', 'eggs'],
    'nums': [1, 2, 3, 4]
}).astype(dtype={
    'words': 'object',
    'nums': 'int8'
})

def to_csv(df, path):
    # Prepend dtypes to the top of df (from https://stackoverflow.com/a/43408736/7607701)
    df.loc[-1] = df.dtypes
    df.index = df.index + 1
    df.sort_index(inplace=True)
    # Then save it to a csv
    df.to_csv(path, index=False)

def read_csv(path):
    # Read types first line of csv
    dtypes = pd.read_csv('tmp.csv', nrows=1).iloc[0].to_dict()
    # Read the rest of the lines with the types from above
    return pd.read_csv('tmp.csv', dtype=dtypes, skiprows=[1])


print('Before: \n{}\n'.format(df.dtypes))

to_csv(df, 'tmp.csv')
df = read_csv('tmp.csv')

print('After: \n{}\n'.format(df.dtypes))

输出:

Before: 
nums       int8
words    object
dtype: object

After: 
nums       int8 # still int8
words    object
dtype: object

【讨论】:

    【解决方案2】:

    #Aaron N. Brock 的修改以允许 parse_dates 以及(加上不更改原始 DataFrame):

    def to_csv(df, path):
        # Prepend dtypes to the top of df
        df2 = df.copy()
        df2.loc[-1] = df2.dtypes
        df2.index = df2.index + 1
        df2.sort_index(inplace=True)
        # Then save it to a csv
        df2.to_csv(path, index=False)
    
    def read_csv(path):
        # Read types first line of csv
        dtypes = {key:value for (key,value) in pd.read_csv(path,    
                  nrows=1).iloc[0].to_dict().items() if 'date' not in value}
    
        parse_dates = [key for (key,value) in pd.read_csv(path, 
                       nrows=1).iloc[0].to_dict().items() if 'date' in value]
        # Read the rest of the lines with the types from above
        return pd.read_csv(path, dtype=dtypes, parse_dates=parse_dates, skiprows=[1])
    

    【讨论】:

    • 对此没有赞?这简直是​​疯了。不错的作品。我想知道数据框是否可以被子类化以包含这些功能。
    • 这是一个很棒的补充!很好,我忽略了原始数据帧的突变。
    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 2021-09-08
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多