pandas.DataFrame.from_dict 更快的替代方案

时间:2021-06-01 10:06:49

标签: python pandas dataframe numpy

我有一个大小相同的 numpy 数组的字典,我想进入一个 DataFrame,其中 numpy 数组中的每个值都变成一列。例如:

import numpy as np
import pandas as np

my_dict = {
    "key_1": np.arange((50_000)),
    "key_2": np.arange((50_000)),
}
df = pd.DataFrame.from_dict(my_dict, orient="index")

#        0      1      2      3      4      5      6      7      8      9      10     ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_1      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_2      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999

# [2 rows x 50000 columns]

如果您运行此程序,您会看到 my_dict 创建速度非常快,但 pandas.DataFrame.from_dict 明显慢。

我正在寻找一种方法来获得性能更好的等价物。

只是为了提供更多上下文,以防万一可以完全跳过此步骤,最终目的是使用任意键名列表重新索引 pandas.DataFrame

occurrences = ["key_1", "key_1", "key_2", "key_1", "key_2"]
df = df.reindex(occurrences)

#        0      1      2      3      4      5      6      7      8      9      10     ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_1      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_1      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_2      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_1      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999
# key_2      0      1      2      3      4      5      6      7      8      9     10  ...  49989  49990  49991  49992  49993  49994  49995  49996  49997  49998  49999

# [5 rows x 50000 columns]

也许是直接从 occurrencesmy_dict 出发的更快方法。

编辑:抱歉,我应该提到,np.arange((50_000)) 只是制作大型数组的一个示例。我可以断言数据看起来像这样,它只是任意值,但长度都相同。此外,我试图避免 Python 循环(例如推导式)并使用 pandasnumpy,因为这些项目的大小可能会变得非常大。

谢谢。

1 个答案:

答案 0 :(得分:3)

你可以这样做:

>>> occurrences = ["key_1", "key_2", "key_3", "key_4", "key_5"]
>>> df = pd.DataFrame(dict.fromkeys(occurrences, range(50_000))).T

如果确实有重复的索引:

>>> occurrences = ['key_1', 'key_1', 'key_2', 'key_1', 'key_2']
>>> df = pd.DataFrame(
             data=np.repeat([np.arange(50_000)], repeats=len(occurrences), axis=0), 
             index=occurrences
         )

如果您已经有一个预定义的 dict。例如,my_dict,使用 transpose:

>>> my_dict = {
    "key_1": np.arange((50_000)),
    "key_2": np.arange((50_000)),
}
>>> %timeit pd.DataFrame.from_dict(my_dict, orient="index")
3.21 s ± 62.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>> %timeit pd.DataFrame.from_dict(my_dict).T
551 µs ± 75 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)