在数据帧中应用函数缓慢

时间:2018-05-16 16:52:02

标签: python pandas dataframe

我有一个如下所示的数据框:

>> df      
  A
0 [{k1:v1, k2:v2}, {k1:v3, k2:v4}]
1 [{k1:v5, k2:v6}, {k1:v7, k2:v8}, {k1:v9, k2:v10}]

即列A是具有相同键的词典列表

我希望在这些列表中提取与第一个dict相对应的值:

  K1 K2 A
0 v1 v2 ...
1 v5 v6 ...

我的解决方案到目前为止有效,但速度特别慢(约50分钟记录为1分钟):

def extract_first_dict(s):
    s['K1'] = s['A'][0]['k1']
    s['K2'] = s['A'][0]['k2']
    return s
df = df.apply(extract_first_dict, axis = 1)

任何人都可以提出更好,更快的方法吗?  谢谢!

3 个答案:

答案 0 :(得分:2)

concat

pd.concat([pd.DataFrame(df.A.str[0].tolist(), index=df.index), df], axis=1)

   k1  k2                                                  A
0  v1  v2  [{'k1': 'v1', 'k2': 'v2'}, {'k1': 'v3', 'k2': ...
1  v5  v6  [{'k1': 'v5', 'k2': 'v6'}, {'k1': 'v7', 'k2': ...

答案 1 :(得分:1)

选项1

您应该发现pd.Series.apply的效率高于pd.DataFrame.apply,因为您只使用一个系列作为输入。

def extract_first(x):
    return list(x[0].values())

df['B'] = df['A'].apply(extract_first)

选项2

您也可以尝试使用列表理解:

df['B'] = [list(x[0].values()) for x in df['A']]

在上述两种情况中,您可以通过以下方式拆分为2列:

df[['C', 'D']] = df['B'].apply(pd.Series)

您应该使用您的数据进行基准测试,以评估这些选项中的任何一个是否足够快,以便用于您的用例。

但是真的......

查看上游,以便以更实用的格式获取数据。 pandas将在一系列字典中不提供矢量化功能。你应该考虑只使用一个词典列表。

答案 2 :(得分:1)

选项1

df.A.str[0].apply(pd.Series)

   k1  k2
0  v1  v2
1  v5  v6

join

df.A.str[0].apply(pd.Series).join(df)

   k1  k2                                                  A
0  v1  v2  [{'k1': 'v1', 'k2': 'v2'}, {'k1': 'v3', 'k2': ...
1  v5  v6  [{'k1': 'v5', 'k2': 'v6'}, {'k1': 'v7', 'k2': ...    ​

选项2

pd.DataFrame([t[0] for t in df.A], df.index)

   k1  k2
0  v1  v2
1  v5  v6

join

pd.DataFrame([t[0] for t in df.A], df.index).join(df)

   k1  k2                                                  A
0  v1  v2  [{'k1': 'v1', 'k2': 'v2'}, {'k1': 'v3', 'k2': ...
1  v5  v6  [{'k1': 'v5', 'k2': 'v6'}, {'k1': 'v7', 'k2': ...

​