高速填充数据框

时间:2016-04-26 11:04:16

标签: python performance pandas dataframe concat

我有一个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 Dataframe,如下所示:

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 / Concatening

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个问题:

  1. 为什么方法2在table很大(比方法1慢得多)时变得那么慢,而它只填充空行?
  2. 关于如何加快这个过程的任何想法?

2 个答案:

答案 0 :(得分:3)

我在过去发现,从一系列词汇表中构建数据帧的速度非常快。我的简单建议是尝试,

public class Child extends Parent{
  public boolean isMeh(){
    return true;
  }

  public void childMethod() {
    System.out.println("child: "+isMeh());
  }

  public static void main(String... args){
    Child child = new Child();
    child.parentMethod();
    child.childMethod();

  }

}

class Parent{
  public boolean isMeh(){
    return false;
  }

  public void parentMethod() {
    System.out.println("parent: "+isMeh());
  }
}

答案 1 :(得分:2)

它和@James的想法几乎相同,但在你的情况下,你有一系列的dicts列表,你想先转换成dicts列表或一系列dicts:< / p>

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'}
相关问题