熊猫数据框执行速度问题

时间:2020-05-25 01:31:34

标签: pandas dataframe

我已经输入了如下的pandas数据框。 “ index_vec”列中的内容为字符串类型。

enter image description here

我想添加一组列,这些列的名称表示“ index_vec”列中的值,而值表示“ index_vec”中该值的计数。一个例子如下:

enter image description here

它显示'-1'列的第0行增加了1,并且'-2'列的第2行也增加了1。请注意,由于数据框的大小,有许多未显示的列。我有以下代码,想知道如何进一步提高执行速度。

for i in range (neg_index, pos_index):
  df[str(i)]= 0
  df[str(i)]= df[str(i)].astype(np.int16)

def add_counts(x):
  # take the string rep of the list and make it into an actual python list of strings
  index_vec = [str(x) for x in ast.literal_eval(x['index_vec'])]
  x[set(index_vec)] = x[set(index_vec)] + [index_vec.count(i) for i in set(index_vec)]
  return x

df=df.apply(add_counts, axis = 1)

1 个答案:

答案 0 :(得分:1)

实际上可以在一个衬套中完成!

您的数据框如下所示:

df = pd.DataFrame({'index_vec': ["[370, -1, -1]", "[1201, 1201]", "[-2, 676, 676]", "[641, 641]", "[811, 811]"]})

        index_vec
0   [370, -1, -1]
1    [1201, 1201]
2  [-2, 676, 676]
3      [641, 641]
4      [811, 811]

我们可以将转换索引向量列拆分为pd.Series并应用value_counts,这将创建您需要的所有列以及它们在每行中的计数。然后,我们将新的df与旧的df结合在一起:

df.join(df['index_vec'].str.strip("[]").str.split(", ").apply(pd.Series.value_counts).fillna(0).astype(np.int16))

输出:


        index_vec   -1  370  1201  676   -2  641  811
0   [370, -1, -1]  2.0  1.0   0.0  0.0  0.0  0.0  0.0
1    [1201, 1201]  0.0  0.0   2.0  0.0  0.0  0.0  0.0
2  [-2, 676, 676]  0.0  0.0   0.0  2.0  1.0  0.0  0.0
3      [641, 641]  0.0  0.0   0.0  0.0  0.0  2.0  0.0
4      [811, 811]  0.0  0.0   0.0  0.0  0.0  0.0  2.0

完整代码:

import pandas as pd
import numpy as np

df = pd.DataFrame({'index_vec': ["[370, -1, -1]", "[1201, 1201]", "[-2, 676, 676]", "[641, 641]", "[811, 811]"]})

df = df.join(df['index_vec'].str.strip("[]").str.split(", ").apply(pd.Series.value_counts).fillna(0).astype(np.int16))

编辑:

我只是想添加,我假定它将比您当前的方法快,因为它只会创建index_vec列表中存在的列,而使用范围可能会创建多余的列可能实际上从未出现过的列。另外,当您在该循环中创建列时,您将向数据帧中添加一列x次。.但是,这里您向df中添加了x列一次。

但是,如果没有在两个实现之间运行计时器的完整数据,我不能确定...但是希望这样做可以为您加快速度。

编辑: 需要额外的列:

import pandas as pd
import numpy as np

neg_index = -100
pos_index = 2000

df = pd.DataFrame({'index_vec': ["[370, -1, -1]", "[1201, 1201]", "[-2, 676, 676]", "[641, 641]", "[811, 811]"]})
df = df.join(df['index_vec'].str.strip("[]").str.split(", ").apply(pd.Series.value_counts).fillna(0).astype(np.int16))

uninitialized = list(set([str(x) for x in range(neg_index, pos_index)]).difference(df.columns.values.tolist()))
df[uninitialized] = pd.DataFrame([[0]*len(uninitialized)], index=df.index)