Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用另一列的值列表在dataframe中创建新列,而不使用;groupby“;_Python_Pandas - Fatal编程技术网

Python 使用另一列的值列表在dataframe中创建新列,而不使用;groupby“;

Python 使用另一列的值列表在dataframe中创建新列,而不使用;groupby“;,python,pandas,Python,Pandas,我处理大型数据集,使pandas group和groupby函数花费很长时间/占用太多内存。我听一些人说groupby可能很慢,但我很难找到更好的解决方案 如果我的dataframe有两列类似于: df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]}) a b 1 1 2 1 2 1 4 1 我希望返回与另一列中的值匹配的值列表: a b l

我处理大型数据集,使pandas group和groupby函数花费很长时间/占用太多内存。我听一些人说groupby可能很慢,但我很难找到更好的解决方案

如果我的dataframe有两列类似于:

df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})

a     b     
1     1     
2     1     
2     1      
4     1     
我希望返回与另一列中的值匹配的值列表:

a     b     list_of_b
1     1        [1]
2     1        [1,1]
2     1        [1,1]
4     1        [1]
我目前使用:

df_group = df.groupby('a')
df['list_of_b'] = df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)

上面的代码适用于小数据帧,但不适用于大数据帧(df>1000000行)。有人有更快的方法吗?

在4K行df上,我得到以下信息:

In [29]:
df_group = df.groupby('a')
​
%timeit df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)
%timeit df['a'].map(df.groupby('a')['b'].apply(list))

1 loops, best of 3: 4.37 s per loop
100 loops, best of 3: 4.21 ms per loop

在4K行df上,我得到以下信息:

In [29]:
df_group = df.groupby('a')
​
%timeit df.apply(lambda row: df_group.get_group(row['a'])['b'].tolist(), axis=1)
%timeit df['a'].map(df.groupby('a')['b'].apply(list))

1 loops, best of 3: 4.37 s per loop
100 loops, best of 3: 4.21 ms per loop

仅进行分组,然后连接回原始数据帧似乎要快得多:

def make_lists(df):
    g = df.groupby('a')
    def list_of_b(x):
        return x.b.tolist()
    return df.set_index('a').join(
        pd.DataFrame(g.apply(list_of_b),
                     columns=['list_of_b']),
        rsuffix='_').reset_index()
这将为每个循环提供192ms,并生成1M行,如下所示:

df1 = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
low = 1
high = 10 
size = 1000000
df2 = pd.DataFrame({'a':np.random.randint(low,high,size),
                    'b':np.random.randint(low,high,size)})

make_lists(df1)
Out[155]:
    a   b   list_of_b
0   1   1   [1]
1   2   1   [1, 1]
2   2   1   [1, 1]
3   4   1   [1]
In [156]:


%%timeit
make_lists(df2)
10 loops, best of 3: 192 ms per loop

仅进行分组,然后连接回原始数据帧似乎要快得多:

def make_lists(df):
    g = df.groupby('a')
    def list_of_b(x):
        return x.b.tolist()
    return df.set_index('a').join(
        pd.DataFrame(g.apply(list_of_b),
                     columns=['list_of_b']),
        rsuffix='_').reset_index()
这将为每个循环提供192ms,并生成1M行,如下所示:

df1 = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
low = 1
high = 10 
size = 1000000
df2 = pd.DataFrame({'a':np.random.randint(low,high,size),
                    'b':np.random.randint(low,high,size)})

make_lists(df1)
Out[155]:
    a   b   list_of_b
0   1   1   [1]
1   2   1   [1, 1]
2   2   1   [1, 1]
3   4   1   [1]
In [156]:


%%timeit
make_lists(df2)
10 loops, best of 3: 192 ms per loop

我能想到的最短解决方案:

df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
df.join(pd.Series(df.groupby(by='a').apply(lambda x: list(x.b)), name="list_of_b"), on='a')

   a  b    list_of_b
0  1  1     [1]
1  2  1  [1, 1]
2  2  1  [1, 1]
3  4  1     [1]

我能想到的最短解决方案:

df = pd.DataFrame({'a':[1,2,2,4], 'b':[1,1,1,1]})
df.join(pd.Series(df.groupby(by='a').apply(lambda x: list(x.b)), name="list_of_b"), on='a')

   a  b    list_of_b
0  1  1     [1]
1  2  1  [1, 1]
2  2  1  [1, 1]
3  4  1     [1]

创建一个值列表是有问题的,因为pandas希望将其转换为一个系列并在索引上对齐,您能否尝试
df['list_of_b']=df['a'].map(df.groupby('a')['b'].apply(list))
for speed创建一个值列表是有问题的,因为pandas希望将其转换为一个系列并在索引上对齐,你能试试速度方面的
df['list\u of_b']=df['a'].map(df.groupby('a')['b'].apply(list))