首页 > 解决方案 > 为什么在具有 2.5 亿行的数据框中搜索/评估对象列非常慢?

问题描述

我有一个 2.35 亿行的数据框。其中一列是具有城市名称的对象,例如芝加哥、卢森堡等。

当我做一个简单的熊猫过滤器时:

result = data[(data['CITY'] == 'Louxemburg')]

它需要永远。超过 1.5 小时。

当我按以下方式诉诸DASK时:

ddask = dd.from_pandas(data, npartitions=15)
result = ddask[(ddask['CITY'] == 'Louxemburg')].compute(scheduler='processes')

大约需要45分钟。

我真的认为这样一个简单的评估不应该花这么长时间。我错过了什么吗?

标签: pythonpandasperformance

解决方案


我不确定你的数据有多大,但根据你分享的内容,我相信你的记忆有问题。如果您需要加载每个查询中的所有列,则可能没有任何工具可以帮助您。但是,如果您打算从某些列中提取信息,Bodo 可以让您的生活更轻松。本质上,Bodo 通过优化顺序操作来减少内存使用。例如,Bodo 通过不加载未使用的 Parquet 列来释放内存空间。您可以在此链接找到 Bodo 的安装说明:https ://docs.bodo.ai/latest/source/install.html

我稍微修改了您的代码并使用了三列而不是所有列。然后,我用 Pandas 运行了你的代码,运行了大约 6 分钟。你的数据一定比我的大得多,因为它需要超过 1.5 小时才能运行。为了提高代码的性能和可扩展性,我使用 Bodo 运行相同的代码,耗时不到 25 秒。

数据生成注意事项:我生成了一个包含 10 列和 2.35 亿行的大型数据集。然后,我添加了另一个名为 CITY 的列,其中随机填充了 24 个城市名称。为了使生成的数据更重,另外两列的行已替换为 CITY 列内容,然后将数据保存为 Parquet 文件。

#data generation

import pandas as pd
import numpy as np
import random

#making a 10 columns dataframe filled
df = pd.DataFrame(np.random.randn(235000000, 10), columns = list('ABCDEFGHIJ'))

#making the City column filled randomly from 24 city names

df['CITY'] = df['J'].apply(lambda x: random.choice(['Chicago', 'Tokyo', 'Delhi', 'Cairo', 
                                                       'Dhaka', 'Mumbai', 'Beijing', 'Osaka', 
                                                       'Mexico City', 'Shanghai', 'Sao Paulo', 
                                                       'Los angeles', 'Boston', 'San Diego', 'Louxemburg', 
                                                       'Austin', 'London', 'Denver', 'Pittsburgh',
                                                       'Orlando', 'Memphis', 'Phoenix', 'Tehran']))

#replacing two columns with CITY column
df['H'] = df['CITY']
df['I'] = df['CITY']

df.to_parquet("data.pq")

使用熊猫:

import time 
import pandas as pd
import numpy as np

start = time.time()
df = pd.read_parquet("data.pq")
df = df[['A','B','CITY']]
result = df.loc[df['CITY'] == 'Louxemburg']
end = time.time()
print("computation time: ", end - start)
print(result.head())

output:
computation time:  322.3528618812561
           A         B        CITY
1  -0.553538  1.214924  Louxemburg
16  1.191735  0.437258  Louxemburg
19 -0.973316 -0.220664  Louxemburg
27  0.481840  2.833082  Louxemburg
33  0.093671  0.142565  Louxemburg

与博多:

%%px
import pandas as pd
import numpy as np
import bodo
import time

@bodo.jit(distributed = ['df'])
def filter_data():
    start = time.time()
    df = pd.read_parquet("q3.pq")
    df = df[['A','B','CITY']]
    df = df.loc[df['CITY'] == 'Louxemburg']
    end = time.time()
    print("computation time: ", end - start)
    print(df.head())
    return df

df = filter_data()

output:
[stdout:0] 
computation time:  24.971635405003326
           A         B        CITY
1  -0.553538  1.214924  Louxemburg
16  1.191735  0.437258  Louxemburg
19 -0.973316 -0.220664  Louxemburg
27  0.481840  2.833082  Louxemburg
33  0.093671  0.142565  Louxemburg

免责声明:我在 Bodo.ai 担任数据科学家倡导者。


推荐阅读