2017-05-20 117 views
1

我已经看到了一些“在熊猫数据框中插入一行”的答案,但是他们通常假设有一行插入,或者与我所寻找的略有不同。熊猫:插入没有循环的行

我打算根据条件多次从另一个数据帧插入df

下面的代码“工作”,因为它给了我我正在寻找的东西,但是我想知道这是否可以在没有for循环的情况下完成。

df = pd.DataFrame({ 
     'a':[1,2,3,2,3,1,1,2,1,2,3,3,1,3], 
     'b':[0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
    }) 

df2 = pd.DataFrame(columns = df.columns) 

row_fill = pd.DataFrame({'a':[100],'b':[200]}) 

for i in df.index: 
    if df['a'][i] == 2: 
     df2 = df2.append(row_fill) 

    df2 = df2.append(df.loc[i]) 

df2.reset_index(inplace = True, drop = True) 
df = df2 

任何帮助表示赞赏。

回答

1

我会做这种方式:

来源DF:

In [153]: df 
Out[153]: 
    a b 
0 1 0 
1 2 0 
2 3 0 
3 2 0 
4 3 0 
5 1 0 
6 1 0 
7 2 0 
8 1 0 
9 2 0 
10 3 0 
11 3 0 
12 1 0 
13 3 0 

解决方案:

In [154]: idx = np.argwhere(df.a == 2) # Pandas alternative: idx = df.index[df.a == 2] 

In [155]: new = pd.concat([row_fill] * len(idx)).set_index(idx-1) 

In [156]: new 
Out[156]: 
    a b 
0 100 200 
2 100 200 
6 100 200 
8 100 200 

同样可以用数据帧的构造函数来实现:

new = pd.DataFrame(row_fill.values.tolist() * len(idx), 
        columns=row_fill.columns, index=idx-1) 

现在我们可以连接dfnew,指数排序中所产生的DF和重置索引:

In [157]: res = pd.concat([df, new]).sort_index().reset_index(drop=True) 

In [158]: res 
Out[158]: 
     a b 
0  1 0 
1 100 200 
2  2 0 
3  3 0 
4 100 200 
5  2 0 
6  3 0 
7  1 0 
8  1 0 
9 100 200 
10 2 0 
11 1 0 
12 100 200 
13 2 0 
14 3 0 
15 3 0 
16 1 0 
17 3 0 
+0

谢谢@MaxU - 我只是通过这个正确的思维了。我对numpy很不熟悉。但显然它的作品! – pshep123

+0

@ pshep123,欢迎您:)如果您不喜欢Numpy,我们可以使用:'idx = df.index [df.a == 2]'而不是 – MaxU

+0

这太好了,再次感谢@MaxU。我分解了最后一个'.concat()'函数,只是为了看看发生了什么。是不是因为'df'在那个'.concat()'中是第一个,尽管他们有相同的索引,它仍然在'new'之前? – pshep123