如何重复一个 Pandas DataFrame?

80

这是我应该重复5次的 DataFrame:

>>> x = pd.DataFrame({'a':1,'b':2}, index = range(1))
>>> x
   a  b
0  1  2

我希望得到这样的结果:

>>> x.append(x).append(x).append(x)
   a  b
0  1  2
0  1  2
0  1  2
0  1  2

但是一定有比追加4次更聪明的方法。实际上,我正在处理的DataFrame应该重复50次。

我还没有找到任何实用的东西,包括像np.repeat这样的工具——它在DataFrame上不起作用。

有人可以帮忙吗?

7个回答

131

您可以使用concat函数:

In [13]: pd.concat([x]*5)
Out[13]: 
   a  b
0  1  2
0  1  2
0  1  2
0  1  2
0  1  2

如果你只想重复值而不是索引,你可以这样做:

In [14]: pd.concat([x]*5, ignore_index=True)
Out[14]: 
   a  b
0  1  2
1  1  2
2  1  2
3  1  2
4  1  2

34

我认为现在使用iloc更加干净/快速:

In [11]: np.full(3, 0)
Out[11]: array([0, 0, 0])

In [12]: x.iloc[np.full(3, 0)]
Out[12]:
   a  b
0  1  2
0  1  2
0  1  2

更普遍地,您可以使用tilerepeatarange

In [21]: df = pd.DataFrame([[1, 2], [3, 4]], columns=["A", "B"])

In [22]: df
Out[22]:
   A  B
0  1  2
1  3  4

In [23]: np.tile(np.arange(len(df)), 3)
Out[23]: array([0, 1, 0, 1, 0, 1])

In [24]: np.repeat(np.arange(len(df)), 3)
Out[24]: array([0, 0, 0, 1, 1, 1])

In [25]: df.iloc[np.tile(np.arange(len(df)), 3)]
Out[25]:
   A  B
0  1  2
1  3  4
0  1  2
1  3  4
0  1  2
1  3  4

In [26]: df.iloc[np.repeat(np.arange(len(df)), 3)]
Out[26]:
   A  B
0  1  2
0  1  2
0  1  2
1  3  4
1  3  4
1  3  4
注意:这适用于非整数索引的数据帧(和系列)。

为什么这个方案比其他解决方案更加简洁? - Michael
这是一个更好的解决方案。 - Talha Anwar
这比当前被接受的答案快得多。 - spettekaka

11
尝试使用numpy.repeat
>>> import numpy as np
>>> df = pd.DataFrame(np.repeat(x.to_numpy(), 5, axis=0), columns=x.columns)
>>> df
   a  b
0  1  2
1  1  2
2  1  2
3  1  2
4  1  2

这比pd.concat快至少2倍。 - rdmolony
这就是我想要的答案。快速、整洁且易于理解。 - Isaac Sim

3

通常情况下,我不会重复或者追加文本,除非你的问题确实需要这样做——这种做法效率极低且通常源于不理解正确解决问题的方式。

我不了解你具体的使用情况,但如果你将数值存储为

values = array(1, 2)
df2 = pd.DataFrame(index=arange(0,50),  columns=['a', 'b'])
df2[['a', 'b']] = values

会做这项工作。也许您想更好地解释您想要实现的目标?

1
我有一个数据框,每个标识符都缺少一行。我想要在其中插入这一行,所以我要做的是将这一行重复N次,并将其附加到原始数据框中,然后重新排序。 - lsheng

2

如果没有使用 numpy,我们也可以使用 Index.repeatloc(或reindex):

x.loc[x.index.repeat(5)].reset_index(drop=True)

或者

x.reindex(x.index.repeat(5)).reset_index(drop=True)

输出:

   a  b
0  1  2
1  1  2
2  1  2
3  1  2
4  1  2

2

追加也应该可以工作:

In [589]: x = pd.DataFrame({'a':1,'b':2},index = range(1))

In [590]: x
Out[590]: 
   a  b
0  1  2

In [591]: x.append([x]*5, ignore_index=True) #Ignores the index as per your need
Out[591]: 
   a  b
0  1  2
1  1  2
2  1  2
3  1  2
4  1  2
5  1  2

In [592]: x.append([x]*5)
Out[592]: 
   a  b
0  1  2
0  1  2
0  1  2
0  1  2
0  1  2
0  1  2

0

在我看来,按行lambda应用是一种通用的方法:

df = pd.DataFrame([[1, 2], [3, 4]], columns=["A", "B"])

df.apply(lambda row: row.repeat(2), axis=0) #.reset_index()

Out[1]: 
    A   B
0   1   2
0   1   2
1   3   4
1   3   4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接