使用to_csv时如何保留数据帧的dtypes?

Fee*_*phy 6 python pandas

为了降低内存成本,我使用以下命令指定了我的 Pandas 数据帧的 dtypes astype()

df['A'] = df['A'].astype(int8)
Run Code Online (Sandbox Code Playgroud)

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

cin*_*n21 8

A modification of #Aaron N. Brock to allow parse_dates as well (plus not change original 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])
Run Code Online (Sandbox Code Playgroud)


Aar*_*ock 5

这是一种方法:

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 /sf/answers/3038611551/)
    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))
Run Code Online (Sandbox Code Playgroud)

输出:

Before: 
nums       int8
words    object
dtype: object

After: 
nums       int8 # still int8
words    object
dtype: object
Run Code Online (Sandbox Code Playgroud)