高速填充数据框
Filling a dataframe with high speed
我有一个 pandas 系列,其中每个单元格都是一个字典:
data.individus.head(5)
Out[25]:
0 [{'dateDeNaissance': 1954-09-14 00:00:00, 'enc...
1 [{'dateDeNaissance': 1984-09-14 00:00:00, 'enc...
2 [{'enceinte': False, 'dateDeNaissance': 1981-0...
3 [{'dateDeNaissance': 1989-09-14 00:00:00, 'enc...
4 [{'enceinte': False, 'dateDeNaissance': 1989-0...
Name: individus, dtype: object
我想使用每个词典构建一个 pandas 数据框,如下所示:
t_individus.ix[:, ['dateDeNaissance', 'enceinte']].head()
Out[14]:
dateDeNaissance enceinte
0 1954-09-14 00:00:00 False
1 1984-09-14 00:00:00 False
2 1981-09-14 00:00:00 False
3 1989-09-14 00:00:00 False
4 1989-09-14 00:00:00 False
请注意,我有更多键 (~50),但我在示例中显示了 2 个。
我尝试了两种不同的方法,但我对处理速度并不完全满意:
1/ 连接
serie = data.foo # 110199 lines
keys = get_all_possible_keys(serie) # 48 keys (process time: 0.8s)
table = pd.DataFrame(columns=list(keys))
for i in serie:
df = pd.DataFrame(list(i.items()))
df = df.transpose()
df.columns = df.iloc[0]
df = df.reindex(df.index.drop(0))
table = pd.concat([table, df], axis=0)
开始时很快,然后随着table
变大而慢慢减小。整个过程大约需要1个小时。
2/预分配内存,逐行填充
serie = data.foo
keys = get_all_possible_keys(serie)
len_serie = len(serie)
# -- Pre-allocate memory by declaring size
table = pd.DataFrame(np.nan,
index=range(0, len_serie),
columns=list(keys))
# -- Fill row by row
k = 0
for i in serie:
table.loc[k] = pd.Series(i[0])
k += 1
处理时间取决于 table
的大小。子集(~10k 行)的速度要快得多,而完整数据集(110k 行)的速度要慢得多。
2 个问题:
- 当
table
很大(比方法 1 慢得多)时,为什么方法 2 变得如此慢,而它只填充空行?
- 关于如何加快流程的任何想法?
我过去发现从字典列表构建数据框的速度出奇地快。我的简单建议是尝试,
dataframe = pandas.DataFrame(data.foo.tolist())
这与@James 的想法几乎相同,但在您的情况下,您有一系列字典列表,您希望首先将其转换为字典列表或一系列字典:
In [12]: s
Out[12]:
0 [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}]
1 [{'a': 'a1', 'b': 'b1', 'c': 'c1'}]
dtype: object
In [13]: pd.DataFrame(s.sum())
Out[13]:
a b c
0 aaa bbb ccc
1 a1 b1 c1
In [14]: s.sum()
Out[14]: [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}, {'a': 'a1', 'b': 'b1', 'c': 'c1'}]
使用 .tolist()
:
In [15]: pd.DataFrame(s.tolist())
Out[15]:
0
0 {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
1 {'a': 'a1', 'b': 'b1', 'c': 'c1'}
我有一个 pandas 系列,其中每个单元格都是一个字典:
data.individus.head(5)
Out[25]:
0 [{'dateDeNaissance': 1954-09-14 00:00:00, 'enc...
1 [{'dateDeNaissance': 1984-09-14 00:00:00, 'enc...
2 [{'enceinte': False, 'dateDeNaissance': 1981-0...
3 [{'dateDeNaissance': 1989-09-14 00:00:00, 'enc...
4 [{'enceinte': False, 'dateDeNaissance': 1989-0...
Name: individus, dtype: object
我想使用每个词典构建一个 pandas 数据框,如下所示:
t_individus.ix[:, ['dateDeNaissance', 'enceinte']].head()
Out[14]:
dateDeNaissance enceinte
0 1954-09-14 00:00:00 False
1 1984-09-14 00:00:00 False
2 1981-09-14 00:00:00 False
3 1989-09-14 00:00:00 False
4 1989-09-14 00:00:00 False
请注意,我有更多键 (~50),但我在示例中显示了 2 个。
我尝试了两种不同的方法,但我对处理速度并不完全满意:
1/ 连接
serie = data.foo # 110199 lines
keys = get_all_possible_keys(serie) # 48 keys (process time: 0.8s)
table = pd.DataFrame(columns=list(keys))
for i in serie:
df = pd.DataFrame(list(i.items()))
df = df.transpose()
df.columns = df.iloc[0]
df = df.reindex(df.index.drop(0))
table = pd.concat([table, df], axis=0)
开始时很快,然后随着table
变大而慢慢减小。整个过程大约需要1个小时。
2/预分配内存,逐行填充
serie = data.foo
keys = get_all_possible_keys(serie)
len_serie = len(serie)
# -- Pre-allocate memory by declaring size
table = pd.DataFrame(np.nan,
index=range(0, len_serie),
columns=list(keys))
# -- Fill row by row
k = 0
for i in serie:
table.loc[k] = pd.Series(i[0])
k += 1
处理时间取决于 table
的大小。子集(~10k 行)的速度要快得多,而完整数据集(110k 行)的速度要慢得多。
2 个问题:
- 当
table
很大(比方法 1 慢得多)时,为什么方法 2 变得如此慢,而它只填充空行? - 关于如何加快流程的任何想法?
我过去发现从字典列表构建数据框的速度出奇地快。我的简单建议是尝试,
dataframe = pandas.DataFrame(data.foo.tolist())
这与@James 的想法几乎相同,但在您的情况下,您有一系列字典列表,您希望首先将其转换为字典列表或一系列字典:
In [12]: s
Out[12]:
0 [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}]
1 [{'a': 'a1', 'b': 'b1', 'c': 'c1'}]
dtype: object
In [13]: pd.DataFrame(s.sum())
Out[13]:
a b c
0 aaa bbb ccc
1 a1 b1 c1
In [14]: s.sum()
Out[14]: [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}, {'a': 'a1', 'b': 'b1', 'c': 'c1'}]
使用 .tolist()
:
In [15]: pd.DataFrame(s.tolist())
Out[15]:
0
0 {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
1 {'a': 'a1', 'b': 'b1', 'c': 'c1'}