gpt4 book ai didi

python - pandas 1.2.1 to_csv performance with datetime 作为索引并设置 date_format

转载 作者:行者123 更新时间:2023-12-04 15:07:11 27 4
gpt4 key购买 nike

升级到 Python 3.8 和 pandas 1.2.1 后,我观察到性能大幅下降。

下面的简单代码需要将近8分钟才能完成:

import sys
import pandas as pd
import csv
import datetime

pd.show_versions()

start = datetime.datetime(2020,1,1,0,0,0)
print(str(start))
data = { 'timestamp': [], 'i': []}
for i in range(0, 2000000):
data['timestamp'].append(str(start))
data['i'].append(i)

df = pd.DataFrame(data)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df.set_index('timestamp', inplace=True)
print(df.tail(10), flush=True)

df.to_csv('/DATA1/TEMP/df.csv', sep=',', date_format='%Y-%m-%d %H:%M:%S', quoting=csv.QUOTE_ALL)
print("DONE", flush=True)

这个脚本在我的虚拟环境中的输出是:

/home/user/venv-test/lib/python3.8/site-packages/setuptools/distutils_patch.py:25: UserWarning: Distutils was imported before Setuptools. This usage is discouraged and may exhibit undesirable behaviors or errors. Please use Setuptools' objects directly or at least import Setuptools first.
warnings.warn(

INSTALLED VERSIONS
------------------
commit : 9d598a5e1eee26df95b3910e3f2934890d062caa
python : 3.8.7.final.0
python-bits : 64
OS : Linux
OS-release : 3.10.0-1062.el7.x86_64
Version : #1 SMP Wed Aug 7 18:08:02 UTC 2019
machine : x86_64
processor : x86_64
byteorder : little
LC_ALL : None
LANG : en_US.UTF-8
LOCALE : en_US.UTF-8

pandas : 1.2.1
numpy : 1.19.5
pytz : 2020.5
dateutil : 2.8.1
pip : 21.0
setuptools : 49.2.1
Cython : 0.29.21
pytest : None
hypothesis : None
sphinx : None
blosc : None
feather : None
xlsxwriter : None
lxml.etree : None
html5lib : None
pymysql : None
psycopg2 : 2.8.6 (dt dec pq3 ext lo64)
jinja2 : None
IPython : None
pandas_datareader: None
bs4 : None
bottleneck : None
fsspec : None
fastparquet : None
gcsfs : None
matplotlib : None
numexpr : None
odfpy : None
openpyxl : None
pandas_gbq : None
pyarrow : None
pyxlsb : None
s3fs : None
scipy : 1.6.0
sqlalchemy : None
tables : None
tabulate : None
xarray : None
xlrd : None
xlwt : None
numba : None
2020-01-01 00:00:00

timestamp
2020-01-01 1999990
2020-01-01 1999991
2020-01-01 1999992
2020-01-01 1999993
2020-01-01 1999994
2020-01-01 1999995
2020-01-01 1999996
2020-01-01 1999997
2020-01-01 1999998
2020-01-01 1999999
DONE

real 7m49.337s
user 7m39.805s
sys 0m14.665s

在我的生产环境中,这是在包含大约 20 列的数据帧上运行的,to_csv() 调用的时间从几分钟变成了 40 多个小时。

我在这里遗漏了什么明显的东西吗?或者在这个特定版本的 pandas 中可能存在一些已知错误?

我通过将文件转储到不同硬盘驱动器上的几个不同分区来检查我的系统是否不受 IO 限制。此外,该进程在将数据帧转储为 CSV 时保持 100% 的 CPU 使用率,这与 IO 绑定(bind)系统不一致。

最佳答案

  • 我不能告诉你为什么,但我可以告诉你是什么。

问题是由于使用 date_format 并且 datetime 是索引引起的。

  • Stef 所述: BUG (Performance): Performance of to_csv varies significantly depending on when/how index is set #37484
  • date_format='%Y-%m-%d %H:%M:%S' 使过程变慢,因为它似乎没有被矢量化。
    • 此参数似乎导致进程将行写入文件,然后更改文件中的格式,或者更改行的日期格式,然后写入。
    • 我可以看到这正在发生,因为我停止了进程,并且文件已部分写入。
  • 在这种情况下,所有数据的时间都是 00:00:00,pandas 不会显示该时间,但是如果时间不是 00:00:00 在列中,然后显示所有时间组件。
    • 如果你写入一个没有date_format的文件,当所有的时间部分都是00:00:00时,时间戳的格式将会是'% Y-%m-%d'.
start = datetime(2020,1,1,0,0,0)
df.to_csv('df.csv', sep=',', quoting=csv.QUOTE_ALL)

# resulting csv
"timestamp","i"
"2020-01-01","0"
"2020-01-01","1"
"2020-01-01","2"
  • 如果你写入一个没有date_format的文件,当所有的时间部分都是00:00:01时,时间戳的格式将会是'% Y-%m-%d %H:%M:%S'.
start = datetime(2020,1,1,0,0,1)
df.to_csv('df.csv', sep=',', quoting=csv.QUOTE_ALL)

# resulting csv
"timestamp","i"
"2020-01-01 00:00:01","0"
"2020-01-01 00:00:01","1"
"2020-01-01 00:00:01","2"

通过在.to_csv()之前设置格式解决问题,或者重置datetime索引。

  • 如果您需要设置日期时间列的格式,请在写入 csv 之前执行。
  • 使用 df.index.strftime('%Y-%m-%d %H:%M:%S')df[some column].dt.strftime( '%Y-%m-%d %H:%M:%S')
  • '%Y-%m-%d %H:%M:%S' 已经是 datetime dtype 的默认格式>,因此无需将 datetime 格式的列重新格式化为 string
df.index = df.index.strftime('%Y-%m-%d %H:%M:%S')
df.to_csv('df.csv', sep=',', quoting=csv.QUOTE_ALL)
df.reset_index(inplace=True)
df.to_csv('df.csv', sep=',', date_format='%Y-%m-%d %H:%M:%S', index=False, quoting=csv.QUOTE_ALL)

测试数据

  • 可以合并编写测试数据框的代码
  • datetime(2020,1,1,0,0,0) 已经是一个datetime dtype,所以没有理由做 df['timestamp'] = pd.to_datetime(df['timestamp'])
import pandas as pd
from datetime import datetime

cols = 2000000
df = pd.DataFrame({'i': range(cols)}, index=[datetime(2020,1,1,0,0,1)] * cols)

df.to_csv('df.csv', sep=',', quoting=csv.QUOTE_ALL)

关于python - pandas 1.2.1 to_csv performance with datetime 作为索引并设置 date_format,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65903287/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com