我有以下內容df:
ID Number Number 2 Number 3
1 10001 NaN NaN 5
2 10001 25 NaN 12
3 10001 78 4 NaN
4 10002 3 NaN NaN
5 10002 234 201 NaN
6 10002 NaN 510 34
7 10003 NaN 765 NaN
8 10003 NaN 422 NaN
9 10003 NaN 753 56
10 10003 231 7587 2345
我想構造資料,以便按列洗掉前 NaN 行。
導致df:
ID Number Number 2 Number 3
1 10001 25 4 5
2 10001 78 NaN 12
3 10001 NaN NaN NaN
4 10002 3 201 34
5 10002 234 510 NaN
6 10002 NaN NaN NaN
7 10003 231 765 56
8 10003 NaN 422 2345
9 10003 NaN 753 NaN
10 10003 NaN 7587 NaN
我實際上是在嘗試將列資料向上移動 n 行,具體取決于該列的資料開始位置,因此在第一行中ID至少有一Number列中始終存在資料。
我已經嘗試過first_row_index,但這不適用于個別列
我已經嘗試過dropna,但我找不到一個解決方案來定義每列要洗掉的行數。
uj5u.com熱心網友回復:
df1 = df.melt('ID').dropna()
df1['var1'] = df1.groupby(['variable', 'ID']).cumcount()
df1.pivot(['ID', 'var1'], 'variable', 'value').reset_index(0)
variable ID Number Number 2 Number 3
var1
0 10001 25.0 4.0 5.0
1 10001 78.0 NaN 12.0
0 10002 3.0 201.0 34.0
1 10002 234.0 510.0 NaN
0 10003 231.0 765.0 56.0
1 10003 NaN 422.0 2345.0
2 10003 NaN 753.0 NaN
3 10003 NaN 7587.0 NaN
uj5u.com熱心網友回復:
編輯:
我錯過了ID條件。在這種情況下,您需要使用 groupby。
# In one liner
df.groupby('ID').apply(lambda x:x.reset_index().apply(lambda y: y.shift(-y.first_valid_index())).set_index('index'))
解釋:
- 按 ID 對資料框進行分組
- 第
apply一個(帶有 的lambda x)接收分組的資料幀作為引數reset_index()是使分組的資料幀以索引 0 開頭(否則它將使用整個資料幀中的索引)
- 第二個
apply(一個帶有lambda y)接收分組資料框的列作為引數- 獲取并向
first_valid_index上移動
- 獲取并向
- 由于重置的索引現在沒有用了,我們
index將要用作索引的列歸還
ID Number Number 2 Number 3
0 10001.0 25.0 4.0 5.0
1 10001.0 78.0 NaN 12.0
2 10001.0 NaN NaN NaN
3 10002.0 3.0 201.0 34.0
4 10002.0 234.0 510.0 NaN
5 10002.0 NaN NaN NaN
6 10003.0 231.0 765.0 56.0
7 10003.0 NaN 422.0 2345.0
8 10003.0 NaN 753.0 NaN
9 10003.0 NaN 7587.0 NaN
df.apply(lambda x: x.shift(-x.first_valid_index()))
uj5u.com熱心網友回復:
使用資料框的堆疊版本,然后按每組 列的前導 NaN 上的數字移動:
(df.set_index('ID', append=True).stack(dropna=False)
.groupby(level=[1,2])
.apply(lambda s: s.shift(-(~s.notna().cummax()).sum()))
.unstack(-1)
.reset_index()
)
輸出:
ID Number Number 2 Number 3
1 10001 25.0 4.0 5
2 10001 78.0 NaN 12
3 10001 NaN NaN NaN
4 10002 3.0 201.0 34
5 10002 234.0 510.0 NaN
6 10002 NaN NaN NaN
7 10003 231.0 765.0 56
8 10003 NaN 422.0 2345
9 10003 NaN 753.0 NaN
10 10003 NaN 7587.0 NaN
uj5u.com熱心網友回復:
這是另一種方法,第一列總是有一個值,對于任何 ID,只有最后一行會有 NaN,如果有的話
# melt to make it a single column, so we drop all the NAN cells/rows
df2=df.melt('ID').dropna(axis=0)
# count the number of values for an ID
df2['ID_Count'] = df2.groupby(['ID']).cumcount()
# Group the result into a set of 3, since we have three columns number, number_2, number_3
df2['new_var'] = (df2['ID_Count'] // (3))
# Generate a new column name
df2['new_var_group'] = 'Number_' df2.groupby(['ID','new_var']).cumcount().astype(str)
# finally reverse the melt and gnerate the table same as before
df2 = df2.pivot_table(index=['ID','new_var' ], columns='new_var_group', values='value').reset_index().drop(columns='new_var', axis=1)
df2
new_var_group ID Number_0 Number_1 Number_2
0 10001 25.0 78.0 4.0
1 10001 5.0 12.0 NaN
2 10002 3.0 234.0 201.0
3 10002 510.0 34.0 NaN
4 10003 231.0 765.0 422.0
5 10003 753.0 7587.0 56.0
6 10003 2345.0 NaN NaN
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/479031.html
