Python Pandas在数据帧中复制行

wuh*_*uha 54 python dataframe pandas

如果数据如下:

Store,Dept,Date,Weekly_Sales,IsHoliday
1,1,2010-02-05,24924.5,FALSE
1,1,2010-02-12,46039.49,TRUE
1,1,2010-02-19,41595.55,FALSE
1,1,2010-02-26,19403.54,FALSE
1,1,2010-03-05,21827.9,FALSE
1,1,2010-03-12,21043.39,FALSE
1,1,2010-03-19,22136.64,FALSE
1,1,2010-03-26,26229.21,FALSE
1,1,2010-04-02,57258.43,FALSE
Run Code Online (Sandbox Code Playgroud)

我想复制IsHoliday等于TRUE的行,我可以这样做:

is_hol = df['IsHoliday'] == True
df_try = df[is_hol]
df=df.append(df_try*10)
Run Code Online (Sandbox Code Playgroud)

但有没有更好的方法来做到这一点因为我需要将假日行复制5次,如果使用上述方法我必须追加5次.

Kar*_* D. 54

你可以放入df_try一个列表,然后做你想到的:

>>> df.append([df_try]*5,ignore_index=True)

    Store  Dept       Date  Weekly_Sales IsHoliday
0       1     1 2010-02-05      24924.50     False
1       1     1 2010-02-12      46039.49      True
2       1     1 2010-02-19      41595.55     False
3       1     1 2010-02-26      19403.54     False
4       1     1 2010-03-05      21827.90     False
5       1     1 2010-03-12      21043.39     False
6       1     1 2010-03-19      22136.64     False
7       1     1 2010-03-26      26229.21     False
8       1     1 2010-04-02      57258.43     False
9       1     1 2010-02-12      46039.49      True
10      1     1 2010-02-12      46039.49      True
11      1     1 2010-02-12      46039.49      True
12      1     1 2010-02-12      46039.49      True
13      1     1 2010-02-12      46039.49      True
Run Code Online (Sandbox Code Playgroud)

  • 我添加`ignore_index`参数,以便最终的数据帧有一个合理的索引:`df.append([df_try]*5,ignore_index = True)` (6认同)

sno*_*ear 18

这是一个老问题,但由于它仍然出现在Google的结果中,这是另一种方式.

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1':list("abc"),'col2':range(3)},index = range(3))
Run Code Online (Sandbox Code Playgroud)

假设您要复制col1 ="b"的行.

reps = [3 if val=="b" else 1 for val in df.col1]
df.loc[np.repeat(df.index.values, reps)]
Run Code Online (Sandbox Code Playgroud)

您可以3 if val=="b" else 1使用另一个函数替换列表解释中的另一个函数,如果val =="b"则返回3,如果val =="c"则返回4,依此类推,因此它非常灵活.


Sur*_*rya 17

其他方法是使用concat()函数:

import pandas as pd

In [603]: df = pd.DataFrame({'col1':list("abc"),'col2':range(3)},index = range(3))

In [604]: df
Out[604]: 
  col1  col2
0    a     0
1    b     1
2    c     2

In [605]: pd.concat([df]*3, ignore_index=True) # Ignores the index
Out[605]: 
  col1  col2
0    a     0
1    b     1
2    c     2
3    a     0
4    b     1
5    c     2
6    a     0
7    b     1
8    c     2

In [606]: pd.concat([df]*3)
Out[606]: 
  col1  col2
0    a     0
1    b     1
2    c     2
0    a     0
1    b     1
2    c     2
0    a     0
1    b     1
2    c     2
Run Code Online (Sandbox Code Playgroud)


gro*_*fte 8

在 Pandas 中附加和连接通常很慢,所以我建议只创建一个新的行列表并将其转换为数据帧(除非附加单行或连接几个数据帧)。

import pandas as pd

df = pd.DataFrame([
[1,1,'2010-02-05',24924.5,False],
[1,1,'2010-02-12',46039.49,True],
[1,1,'2010-02-19',41595.55,False],
[1,1,'2010-02-26',19403.54,False],
[1,1,'2010-03-05',21827.9,False],
[1,1,'2010-03-12',21043.39,False],
[1,1,'2010-03-19',22136.64,False],
[1,1,'2010-03-26',26229.21,False],
[1,1,'2010-04-02',57258.43,False]
], columns=['Store','Dept','Date','Weekly_Sales','IsHoliday'])

temp_df = []
for row in df.itertuples(index=False):
    if row.IsHoliday:
        temp_df.extend([list(row)]*5)
    else:
        temp_df.append(list(row))

df = pd.DataFrame(temp_df, columns=df.columns)
Run Code Online (Sandbox Code Playgroud)


Myk*_*tko 6

你可以用一行来完成:

df.append([df[df['IsHoliday'] == True]] * 5, ignore_index=True)
Run Code Online (Sandbox Code Playgroud)

或者

df.append([df[df['IsHoliday']]] * 5, ignore_index=True)
Run Code Online (Sandbox Code Playgroud)


bud*_*mat 5

另一种替代方法append()是首先用条目列表替换列的值,然后explode()(使用ignore_index=True或不使用,取决于您想要的):

df['IsHoliday'] = df['IsHoliday'].apply(lambda x: 5*[x] if (x == True) else x)

df.explode('IsHoliday', ignore_index=True)
Run Code Online (Sandbox Code Playgroud)

这个的好处是,您已经可以在调用中使用列表apply()来构建具有列中修改值的行的副本,以防您以后想这样做......