【问题标题】:Pandas dataframe CSV reduce disk sizePandas 数据帧 CSV 减少磁盘大小
【发布时间】:2019-08-13 10:27:21
【问题描述】:

对于我的大学作业,我必须生成一个包含世界上所有机场距离的 csv 文件...问题是我的 csv 文件重量为 151Mb。我想尽可能减少它:这是我的 csv:

这是我的代码:

# drop all features we don't need
for attribute in df:
    if attribute not in ('NAME', 'COUNTRY', 'IATA', 'LAT', 'LNG'):
        df = df.drop(attribute, axis=1)

# create a dictionary of airports, each airport has the following structure:
# IATA : (NAME, COUNTRY, LAT, LNG)
airport_dict = {}
for airport in df.itertuples():
    airport_dict[airport[3]] = (airport[1], airport[2], airport[4], airport[5])

# From tutorial 4 soulution:
airportcodes=list(airport_dict)
airportdists=pd.DataFrame()
for i, airport_code1 in enumerate(airportcodes):
    airport1 = airport_dict[airport_code1]
    dists=[]
    for j, airport_code2 in enumerate(airportcodes):
        if j > i:
            airport2 = airport_dict[airport_code2]
            dists.append(distanceBetweenAirports(airport1[2],airport1[3],airport2[2],airport2[3]))
        else:
        # little edit: no need to calculate the distance twice, all duplicates are set to 0 distance
            dists.append(0)
    airportdists[i]=dists
airportdists.columns=airportcodes
airportdists.index=airportcodes

# set all 0 distance values to NaN
airportdists = airportdists.replace(0, np.nan)
airportdists.to_csv(r'../Project Data Files-20190322/distances.csv')

我还尝试在保存之前对其重新编制索引:

# remove all NaN values
airportdists = airportdists.stack().reset_index()
airportdists.columns = ['airport1','airport2','distance']

但结果是一个包含 3 列和 1700 万列的数据帧以及 419Mb 的磁盘大小......完全没有改进......

你能帮我缩小我的 csv 文件的大小吗?谢谢!

【问题讨论】:

  • 17 000 000 行 * 3 列 / 1024 / 1024 = 48 Mb 如果假设每行一个字符 151 Mb = 平均每行 3 个字符......你想如何缩小你的输出文件?不可能?除非您希望多个文件更小
  • 谢谢@Frenchy,是的,我不确定是否可以减小文件尺寸,这就是我要问的哦
  • 你有几个机场?
  • @Frenchy 9541 机场
  • 不显着。 9541 个机场意味着您有大约 9100 万个机场对,如果您忽略重复项,则为 4550 万个。对于大多数人来说,距离需要 3-4 个字符,分隔符需要一个字符。考虑到 151 MiB 是相当不错的。 CSV 作为纯文本不是很节省空间。除非您使用压缩和/或二进制格式,否则您不会做得更好。 |为什么还是有问题?

标签: python pandas csv dataframe compression


【解决方案1】:

我过去做过类似的申请;这就是我要做的:

文件很难缩小,但是如果你的应用程序需要例如机场与其他机场之间的距离,我建议你创建 9541 文件,每个文件将是机场与其他机场的距离及其名称将是机场的名称。

在这种情况下,文件的加载速度非常快。

【讨论】:

  • 我会尽快试试这个,我会告诉你的 ;-)
【解决方案2】:

问题的标题“..reduce disk size”是通过输出csv的压缩版本来解决的。

airportdists.to_csv(r'../Project Data Files-20190322/distances.csv', compression='zip')

或者更好的 Pandas 0.24.0

airportdists.to_csv(r'../Project Data Files-20190322/distances.csv.zip')

你会发现 csv 被极大地压缩了。

这当然不能解决优化负载和节省时间的问题,也不能解决工作记忆问题。但希望在磁盘空间非常宝贵或正在为云存储付费时有用。

【讨论】:

  • 嗯,是的,我实际上是在寻找不涉及 zip 文件的解决方案:例如使用音乐 mp3 或图像 png、jpeg:我想避免压缩文件,而是使用不同的文件压缩算法以减少磁盘空间
  • 我不太明白。 0.24.0 有多种压缩策略。 zip 只是其中之一。所以我想也许你希望在数据加载到 pandas 时减少工作内存量。为此,这将是一个需要解决的算法/数据结构问题。
【解决方案3】:

我的建议不是存储为 CSV,而是尝试存储在 JSON 等键值对数据结构中。检索将非常快。或者尝试使用 CSV 文件存储空间 1/4 的 parquet 文件格式。

import pandas as pd
import numpy as np
from pathlib import Path
from string import ascii_letters

#created a dataframe
df = pd.DataFrame(np.random.randint(0,10000,size=(1000000, 52)),columns=list(ascii_letters))

df.to_csv('csv_store.csv',index=False)
print('CSV Consumend {} MB'.format(Path('csv_store.csv').stat().st_size*0.000001))
#CSV Consumend 255.22423999999998 MB

df.to_parquet('parquate_store',index=False)
print('Parquet Consumed {} MB'.format(Path('parquate_store').stat().st_size*0.000001))
#Parquet Consumed 93.221154 MB

【讨论】:

  • 欢迎来到 StackOverflow,如果需要理解答案,请添加更多描述和代码,因为它会尽快解决其他人的问题。
【解决方案4】:

最好的压缩方式是存储每个机场的纬度和经度,然后按需计算任意两对之间的距离。比如说,每个机场和标识符的两个 32 位浮点值,大约是 110K 字节。压缩了大约 1300 倍。

【讨论】:

  • 嗨,马克,你能说得更具体点吗?什么是压缩系数?
  • 未压缩位数除以压缩位数。
猜你喜欢
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2013-06-10
相关资源
最近更新 更多