我有一个大约160k行乘24列的大型数据框。我还有一个长度为26的熊猫系列,我想逐行添加到我的数据框中,以形成一个160k行乘50列的最终数据帧,但我的代码非常缓慢。
具体来说这很慢,但它有效:
final = df.apply(lambda x: x.append(my_series), axis=1)
产生正确的最终形状:
Out[49]: (163008, 50)
其中,df.shape
为Out[48]: (163008, 24)
且my_series.shape
为Out[47]: (26,)
此方法适用于<50k行范围内的较小数据帧,但显然不太理想。
使用%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
使用assign:
我一直在接收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
答案 0 :(得分:4)
我们可以使用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
注意:该系列应具有字符串索引元素。
答案 1 :(得分:3)
我认为您需要numpy.tile
numpy.ndarray.reshape
df
新Series
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
值,最后join
:
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
EXPORTS
HeapAlloc = ntdll.RtlAllocateHeap
答案 2 :(得分:2)
看看是否有效 -
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