【问题标题】:Pandas DataFrame slow to show shape or dtypesPandas DataFrame 显示形状或数据类型缓慢
【发布时间】:2023-03-21 09:44:01
【问题描述】:

我对@9​​87654321@ 和pandas 很陌生。感谢您提供任何指导、评论和建议!

这是我的问题:调用df.shapedf.dtypes 后需要几分钟才能返回结果。 DataFrame1,610,658 行和 5 列。三列存储为int64,一列存储为float64,一列存储为datetime64

我使用以下代码在python 中练习加载和转换。 load和transform都有不错的性能,但是我在查看输出时遇到了这个问题。

更新 1:

将部分列设置为索引后,df.shape 时间从 80+s 下降到 1.7s,但df.dtypes 仍停留在 80+s

import pandas as pd

###############
# Load
###############
raw = pd.read_csv("data.zip", compression='zip')

###############
# Transform
###############

payment_method = {
   "Cash": 1
   "Card": 2
}

df = raw. \
    assign(
        # Encode site ids to int. Only two sites in this data
        site     = (raw.site == "A").astype(int),
        # Encode payment types to int
        payment  = 
            [payment_method.get(k, 0) for k in raw.payment],
        # Rescale values
        amount   = raw.amount / 1e6,
        # Convert integer date key to datetime
        sold_date= pd.to_datetime(
            [str(dt) for dt in raw. sold_date],
            format="%Y%m%d")
    )

###############
# Check point
###############

df.shape # pain point I. Took minutes to return
# Out[9]: (1610658, 5)

df.dtypes # pain point II
# Out[10]: 
# site                       int64
# acct_key                   int64
# sold_date         datetime64[ns]
# amount                   float64
# payment                    int64

如果我将数据框转换为numpy.ndarray,我可以立即得到结果。我想我一定错过了什么。请给我一些指导。

非常感谢!

系统:OS X 10.12
Python:3.6.1
Numpy:1.12
熊猫:0.20.2
Jupyter 控制台:5.1.0

【问题讨论】:

  • 如果只执行 print(df) 怎么样?会不会和一些懒惰的评价有关?调用 shape 属性后你会尝试 numpy 的东西吗?
  • @ayhan 谢谢你的回复。 1.print(df) 立即给我结果,如切片和其他数据操作。根据我有限的观察,它只会在提取元数据时变慢,例如IPython 中的属性和方法列表的<tab>。 2.我对Python的懒惰评价了解不多,不好意思。 3. 在Numpy中非常好用
  • 你安装了 Jedi 吗? (您可能没有直接安装它,但它可能是由 jupyter 或 ipython 提供的。)
  • @DSM 是的,Jedi 在我的列表中。我通过conda 设置了我的环境。感谢您的回复
  • @RichardH 你有可以重现问题的样本数据吗?你终于找到解决办法了吗?

标签: python performance pandas dataframe


【解决方案1】:

尝试减小 DataFrame 的大小:

int_columns = df.select_dtypes(include=["int"]).columns
df[int_columns] = df[int_columns].apply(pd.to_numeric, downcast='unsigned')
float_columns = df.select_dtypes(include=["float"]).columns
df[float_columns] = df[float_columns].apply(pd.to_numeric, downcast='float')

【讨论】:

    【解决方案2】:
    1. 您可以使用@Hai 提到的类型转换来减小数据框的大小。还可以考虑使用pd.Categorical 数据类型代替字符串。这在后台用整数替换了字符串,这可能在减少内存使用方面有最显着的改进。更多内容:https://www.dataquest.io/blog/pandas-big-data/

    2. 您还可以通过在导入步骤中使用pd.read_csv()usecols 参数排除不必要的列来减少数据大小。

    3. 如果您想在不一次读取整个数据集的情况下获取行数和/或列数,您可以使用一种称为惰性求值的技术/使用生成器,它一次读取一行。我喜欢对需要在打开和进一步分析之前检查的大型文件执行此操作。

    生成器方法

    num_rows = 0
    
    with open(r'/Users/Username/Downloads/data_set.csv') as file:
        num_cols = len(file.readline().split(','))
        try:
            while next(file):
                num_rows += 1
        except StopIteration:
            pass
    
    shape = (num_rows, num_cols)
    print(shape)
    

    基本上是pandas df.shape的手动但占用内存较少的实现:

    import pandas as pd
    
    df = pd.read_csv(r'/Users/Username/Downloads/data_set.csv')
    print(df.shape)
    

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 1970-01-01
      • 2017-12-12
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2018-01-14
      • 1970-01-01
      相关资源
      最近更新 更多