簡體   English   中英

根據 Pandas 中的多列條件填充 Nan

[英]Fill Nan based on multiple column condition in Pandas

目標是針對兩列(即a、b)填充NaN

a b c d
2,0,1,4
5,0,5,6
6,0,1,1
1,1,1,4
4,1,5,6
5,1,5,6
6,1,1,1
1,2,2,3
6,2,5,6

這樣,對於列b中的固定值,列a應該有 1 到 6 之間的連續值。 然后,將其他行分配給 nan。

代碼片段可以解決問題

import numpy as np
import pandas as pd



maxval_col_a=6
lowval_col_a=1

maxval_col_b=2
lowval_col_b=0
r=list(range(lowval_col_b,maxval_col_b+1))
df=pd.DataFrame(np.column_stack([[2,5,6,1,4,5,6,1,6,],
  [0,0,0,1,1,1,1,2,2,], [1,5,1,1,5,5,1,2,5,],[4,6,1,4,6,6,1,3,6,]]),columns=['a','b','c','d'])

all_df=[]
for idx in r:
  k=df.loc[df['b']==idx].set_index('a').reindex(range(lowval_col_a, maxval_col_a+1, 1)).reset_index()
  k['b']=idx
  all_df.append(k)


df=pd.concat(all_df)

但是,我很好奇 Pandas 是否有更有效和更好的方法。

預計output

   a  b    c    d
0  1  0  NaN  NaN
1  2  0  1.0  4.0
2  3  0  NaN  NaN
3  4  0  NaN  NaN
4  5  0  5.0  6.0
5  6  0  1.0  1.0
0  1  1  1.0  4.0
1  2  1  NaN  NaN
2  3  1  NaN  NaN
3  4  1  5.0  6.0
4  5  1  5.0  6.0
5  6  1  1.0  1.0
0  1  2  2.0  3.0
1  2  2  NaN  NaN
2  3  2  NaN  NaN
3  4  2  NaN  NaN
4  5  2  NaN  NaN
5  6  2  5.0  6.0

創建組合的笛卡爾積:

mi = pd.MultiIndex.from_product([df['b'].unique(), range(1, 7)],
                                names=['b', 'a']).swaplevel()

out = df.set_index(['a', 'b']).reindex(mi).reset_index()
print(out)

# Output
    a  b    c    d
0   1  0  NaN  NaN
1   2  0  1.0  4.0
2   3  0  NaN  NaN
3   4  0  NaN  NaN
4   5  0  5.0  6.0
5   6  0  1.0  1.0
6   1  1  1.0  4.0
7   2  1  NaN  NaN
8   3  1  NaN  NaN
9   4  1  5.0  6.0
10  5  1  5.0  6.0
11  6  1  1.0  1.0
12  1  2  2.0  3.0
13  2  2  NaN  NaN
14  3  2  NaN  NaN
15  4  2  NaN  NaN
16  5  2  NaN  NaN
17  6  2  5.0  6.0

首先使用 cols [a,b]創建一個多索引,然后使用所有組合創建一個新的多索引,然后使用新的多索引重新索引:(顯示所有步驟)

# set both a and b as index (it's a multiindex)
df.set_index(['a','b'],drop=True,inplace=True)
# create the new multindex
new_idx_a=np.tile(np.arange(0,6+1),3)
new_idx_b=np.repeat([0,1,2],6+1)

new_multidx=pd.MultiIndex.from_arrays([new_idx_a,
                            new_idx_b])
# reindex
df=df.reindex(new_multidx)
# convert the multindex back to columns
df.index.names=['a','b']
df.reset_index()

結果:

    a  b    c    d
0   0  0  NaN  NaN
1   1  0  NaN  NaN
2   2  0  1.0  4.0
3   3  0  NaN  NaN
4   4  0  NaN  NaN
5   5  0  5.0  6.0
6   6  0  1.0  1.0
7   0  1  NaN  NaN
8   1  1  1.0  4.0
9   2  1  NaN  NaN
10  3  1  NaN  NaN
11  4  1  5.0  6.0
12  5  1  5.0  6.0
13  6  1  1.0  1.0
14  0  2  NaN  NaN
15  1  2  2.0  3.0
16  2  2  NaN  NaN
17  3  2  NaN  NaN
18  4  2  NaN  NaN
19  5  2  NaN  NaN
20  6  2  5.0  6.0

我們可以通過在b列上使用groupby來做到這一點,然后將a設置為索引並使用numpy.arange添加a的缺失值。
最后,重置索引以獲得預期的結果:

import numpy as np

df.groupby('b').apply(lambda x : x.set_index('a').reindex(np.arange(1, 7))).drop('b', 1).reset_index()

Output:


    b   a   c   d
0   0   1   NaN NaN
1   0   2   1.0 4.0
2   0   3   NaN NaN
3   0   4   NaN NaN
4   0   5   5.0 6.0
5   0   6   1.0 1.0
6   1   1   1.0 4.0
7   1   2   NaN NaN
8   1   3   NaN NaN
9   1   4   5.0 6.0
10  1   5   5.0 6.0
11  1   6   1.0 1.0
12  2   1   2.0 3.0
13  2   2   NaN NaN
14  2   3   NaN NaN
15  2   4   NaN NaN
16  2   5   NaN NaN
17  2   6   5.0 6.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM