【问题标题】:Add Pandas Series as rows to existing dataframe efficiently有效地将 Pandas 系列作为行添加到现有数据框中
【发布时间】:2017-07-25 21:03:52
【问题描述】:

我有一个大约 160k 行 x 24 列的大型数据框。我还有一个长度为 26 的 pandas 系列,我想将它逐行添加到我的数据帧中,以制作一个 160k 行 x 50 列的最终数据帧,但我的代码非常慢。

特别是这很慢,但它有效: final = df.apply(lambda x: x.append(my_series), axis=1)

这会产生正确的最终形状: Out[49]: (163008, 50)

其中,df.shapeOut[48]: (163008, 24)my_series.shapeOut[47]: (26,)

此方法对于

更新:为以下解决方案添加了基准

使用%timeit 使用测试数据框和测试系列进行了一些测试,大小如下: test_df.shape

Out[18]: (156108, 24)

test_series.shape

Out[20]: (26,)

数据框和系列都包含字符串、浮点数、整数、对象等的混合。

接受使用 Numpy 的解决方案

%timeit test_df.join(pd.DataFrame(np.tile(test_series.values, len(test_df.index)).reshape(-1, len(attributes)), index=test_df.index, columns=test_series.index))

10 loops, best of 3: 220 ms per loop

使用分配: 我的测试系列一直收到ValueError: Length of values does not match length of index,但当我使用更简单的系列时,只要它有效,不知道这里发生了什么......

@Divakar 使用自定义函数

%timeit rowwise_concat_df_series(test_df, test_series)

1 loop, best of 3: 424 ms per loop

【问题讨论】:

  • 我认为你应该在你的标签中添加 numpy 以获得一个非常好的 numpy 人来审查这个问题。
  • 数据框中有什么?都是数字(数字)吗?
  • @Divakar 它是浮点数、整数(64 位和 8 位)、字符串、数据帧对象的混合体,而 Series 包含对象 dtypes
  • 那么,您有没有机会在您的实际数据集上计时发布的解决方案?
  • @Divakar 道歉,我对优化其他东西太深入了,我忘记了基准测试。我会将其添加到我的待办事项列表中,并在今天发布结果。谢谢提醒。

标签: pandas numpy


【解决方案1】:

我们可以使用DataFrame.assign()方法:

设置:

In [37]: df = pd.DataFrame(np.random.randn(5, 3), columns=['A','B','C'])

In [38]: my_series = pd.Series([10,11,12], index=['X','Y','Z'])

In [39]: df
Out[39]:
          A         B         C
0  1.129066  0.975453 -0.737507
1 -0.347736 -1.469583 -0.727113
2  1.158480  0.933604 -1.219617
3 -0.689830  3.063868  0.345233
4  0.184248  0.920349 -0.852213

In [40]: my_series
Out[40]:
X    10
Y    11
Z    12
dtype: int64

解决方案:

In [41]: df = df.assign(**my_series)

结果:

In [42]: df
Out[42]:
          A         B         C   X   Y   Z
0  1.129066  0.975453 -0.737507  10  11  12
1 -0.347736 -1.469583 -0.727113  10  11  12
2  1.158480  0.933604 -1.219617  10  11  12
3 -0.689830  3.063868  0.345233  10  11  12
4  0.184248  0.920349 -0.852213  10  11  12

注意:系列应该有 string 索引元素。

PS**variable explained

【讨论】:

  • 我不熟悉你系列前面的双星号,它是做什么的?
  • 它执行字典解包
  • @tbone,我添加了指向另一个 SO 问题/答案的链接,其中详细解释了...
  • 谢谢,我必须将您的解决方案与我接受的另一个答案进行比较,因为我测试了那个答案,而且速度非常快。
  • @tbone,当然!知道哪种方法更快会很有趣
【解决方案2】:

我认为您需要 numpy.tilenumpy.ndarray.reshape 用于新的 dfSeries 值和最后一个 join

df = pd.DataFrame({'A':list('abcdef'),
                   'B':[4,5,4,5,5,4],
                   'C':[7,8,9,4,2,3],
                   'D':[1,3,5,7,1,0],
                   'E':[5,3,6,9,2,4],
                   'F':list('aaabbb')})

print (df)
   A  B  C  D  E  F
0  a  4  7  1  5  a
1  b  5  8  3  3  a
2  c  4  9  5  6  a
3  d  5  4  7  9  b
4  e  5  2  1  2  b
5  f  4  3  0  4  b

s = pd.Series([1,5,6,7], index=list('abcd'))
print (s)
a    1
b    5
c    6
d    7
dtype: int64

df1 = pd.DataFrame(np.tile(s.values, len(df.index)).reshape(-1,len(s)), 
                   index=df.index, 
                   columns=s.index)
print (df1)
   a  b  c  d
0  1  5  6  7
1  1  5  6  7
2  1  5  6  7
3  1  5  6  7
4  1  5  6  7
5  1  5  6  7

df = df.join(df1)
print (df)
   A  B  C  D  E  F  a  b  c  d
0  a  4  7  1  5  a  1  5  6  7
1  b  5  8  3  3  a  1  5  6  7
2  c  4  9  5  6  a  1  5  6  7
3  d  5  4  7  9  b  1  5  6  7
4  e  5  2  1  2  b  1  5  6  7
5  f  4  3  0  4  b  1  5  6  7

【讨论】:

  • 这很好用,我必须将它与@MaxU 答案进行比较,看看哪个更快。
  • 嗯,系列值有不同的类型?不一样?
  • 我的意思是系列包含所有object 数据类型,我的错。
【解决方案3】:

看看这是否有效 -

def rowwise_concat_df_series(df, s):
    a = df.values
    b = s.values

    m,n,r = a.shape + (b.size,)
    out_dtype = np.result_type(a.dtype, b.dtype)
    out_arr = np.empty((m, n + r),dtype=out_dtype)
    out_arr[:,:n] = a
    out_arr[:,n:] = b
    df_out = pd.DataFrame(out_arr)
    return df_out

示例运行 -

In [284]: df
Out[284]: 
   0  1
0  4  1
1  0  1
2  8  2
3  1  8
4  3  3

In [285]: s
Out[285]: 
0    5
1    8
2    2
dtype: int64

In [286]: rowwise_concat_df_series(df, s)
Out[286]: 
   0  1  2  3  4
0  4  1  5  8  2
1  0  1  5  8  2
2  8  2  5  8  2
3  1  8  5  8  2
4  3  3  5  8  2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 2013-09-09
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多