Pandas/Python 根据条件添加行

Mik*_*ike 6 python pandas

我希望根据某些条件在两个现有行之间的数据框中插入一行。

例如,我的数据框:

    import pandas as pd
    df = pd.DataFrame({'Col1':['A','B','D','E'],'Col2':['B', 'C', 'E', 'F'], 'Col3':['1', '1', '1', '1']})
Run Code Online (Sandbox Code Playgroud)

看起来像:

    Col1    Col2    Col3
  0 A       B       1
  1 B       C       1
  2 D       E       1
  3 E       F       1
Run Code Online (Sandbox Code Playgroud)

我希望能够在给定条件的索引 1 和索引 2 之间插入新行:

n = 0   
while n < len(df):
    (df.ix[n]['Col2'] == df.ix[n+1]['Col1']) == False
    Something, Something, insert row
    n+=1
Run Code Online (Sandbox Code Playgroud)

我想要的输出表如下所示:

    Col1    Col2    Col3
  0 A       B       1
  1 B       C       1
  2 C       D       1
  3 D       E       1
  4 E       F       1
Run Code Online (Sandbox Code Playgroud)

我正在努力根据先前和后续记录中的值有条件地插入行。我最终想在我的现实世界示例中执行上述练习,其中包括多个条件,并保留多个列的值(在本示例中是 Col3,但在我的现实世界中它将是多列)

Max*_*axU 5

更新:节省内存的方法 - 首先为新行设置一个带有间隙的新索引:

In [30]: df
Out[30]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    D    E    1
3    E    F    1
Run Code Online (Sandbox Code Playgroud)

如果我们想在索引1和之间插入新行2,我们在位置 处拆分索引2

In [31]: idxs = np.split(df.index, 2)
Run Code Online (Sandbox Code Playgroud)

设置一个新索引(在位置 处有间隙2):

In [32]: df.set_index(idxs[0].union(idxs[1] + 1), inplace=True)

In [33]: df
Out[33]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
3    D    E    1
4    E    F    1
Run Code Online (Sandbox Code Playgroud)

插入带有索引的新行2

In [34]: df.loc[2] = ['X','X',2]

In [35]: df
Out[35]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
3    D    E    1
4    E    F    1
2    X    X    2
Run Code Online (Sandbox Code Playgroud)

排序索引:

In [38]: df.sort_index(inplace=True)

In [39]: df
Out[39]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    X    X    2
3    D    E    1
4    E    F    1
Run Code Online (Sandbox Code Playgroud)

PS您还可以使用以下方法插入 DataFrame 而不是单行df.append(new_df)

In [42]: df
Out[42]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    D    E    1
3    E    F    1

In [43]: idxs = np.split(df.index, 2)

In [45]: new_df = pd.DataFrame([['X', 'X', 10], ['Y','Y',11]], columns=df.columns)

In [49]: new_df.index += idxs[1].min()

In [51]: new_df
Out[51]:
  Col1 Col2  Col3
2    X    X    10
3    Y    Y    11

In [52]: df = df.set_index(idxs[0].union(idxs[1]+len(new_df)))

In [53]: df
Out[53]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
4    D    E    1
5    E    F    1

In [54]: df = df.append(new_df)

In [55]: df
Out[55]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
4    D    E    1
5    E    F    1
2    X    X   10
3    Y    Y   11

In [56]: df.sort_index(inplace=True)

In [57]: df
Out[57]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    X    X   10
3    Y    Y   11
4    D    E    1
5    E    F    1
Run Code Online (Sandbox Code Playgroud)

旧答案:

实现这一目标的一种(多种)方法是拆分 DF 并将其与所需的 DF 按所需顺序连接在一起:

原始DF:

In [12]: df
Out[12]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    D    E    1
3    E    F    1
Run Code Online (Sandbox Code Playgroud)

让我们把它分成两部分([0:1], [2:end]):

In [13]: dfs = np.split(df, [2])

In [14]: dfs
Out[14]:
[  Col1 Col2 Col3
 0    A    B    1
 1    B    C    1,   Col1 Col2 Col3
 2    D    E    1
 3    E    F    1]
Run Code Online (Sandbox Code Playgroud)

现在我们可以按照所需的顺序将其与新的 DF 连接在一起:

In [15]: pd.concat([dfs[0], pd.DataFrame([['C','D', 1]], columns=df.columns), dfs[1]], ignore_index=True)
Out[15]:
  Col1 Col2 Col3
0    A    B    1
1    B    C    1
2    C    D    1
3    D    E    1
4    E    F    1
Run Code Online (Sandbox Code Playgroud)