[英]Missing data, insert rows in Pandas and fill with NAN
我是 Python 和 Pandas 的新手,所以可能有一個我沒有看到的簡單解決方案。
我有許多不連續的數據集,如下所示:
ind A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 3.5 2 0
4 4.0 4 5
5 4.5 3 3
我現在尋找解決方案來獲得以下內容:
ind A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NAN NAN
4 2.0 NAN NAN
5 2.5 NAN NAN
6 3.0 NAN NAN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
問題是,A 中的差距在位置和長度上因數據集而異......
set_index
和reset_index
是你的朋友。
df = DataFrame({"A":[0,0.5,1.0,3.5,4.0,4.5], "B":[1,4,6,2,4,3], "C":[3,2,1,0,5,3]})
首先將列 A 移動到索引:
In [64]: df.set_index("A")
Out[64]:
B C
A
0.0 1 3
0.5 4 2
1.0 6 1
3.5 2 0
4.0 4 5
4.5 3 3
然后用新索引重新索引,這里缺失的數據用 nans 填充。 我們使用Index
對象,因為我們可以命名它; 這將在下一步中使用。
In [66]: new_index = Index(arange(0,5,0.5), name="A")
In [67]: df.set_index("A").reindex(new_index)
Out[67]:
B C
0.0 1 3
0.5 4 2
1.0 6 1
1.5 NaN NaN
2.0 NaN NaN
2.5 NaN NaN
3.0 NaN NaN
3.5 2 0
4.0 4 5
4.5 3 3
最后將索引移回帶有reset_index
的列。 由於我們為索引命名,所以一切都神奇地工作:
In [69]: df.set_index("A").reindex(new_index).reset_index()
Out[69]:
A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
使用上面 EdChum 的答案,我創建了以下函數
def fill_missing_range(df, field, range_from, range_to, range_step=1, fill_with=0):
return df\
.merge(how='right', on=field,
right = pd.DataFrame({field:np.arange(range_from, range_to, range_step)}))\
.sort_values(by=field).reset_index().fillna(fill_with).drop(['index'], axis=1)
用法示例:
fill_missing_range(df, 'A', 0.0, 4.5, 0.5, np.nan)
在這種情況下,我使用新生成的數據框覆蓋您的 A 列並將其合並到您的原始 df 中,然后我使用它:
In [177]:
df.merge(how='right', on='A', right = pd.DataFrame({'A':np.arange(df.iloc[0]['A'], df.iloc[-1]['A'] + 0.5, 0.5)})).sort(columns='A').reset_index().drop(['index'], axis=1)
Out[177]:
A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
因此,在一般情況下,您可以調整帶有開始值和結束值的arange
函數,請注意,當范圍打開關閉時,我在末尾添加了 0.5,並傳遞了一個步長值。
更通用的方法可能是這樣的:
In [197]:
df = df.set_index(keys='A', drop=False).reindex(np.arange(df.iloc[0]['A'], df.iloc[-1]['A'] + 0.5, 0.5))
df.reset_index(inplace=True)
df['A'] = df['index']
df.drop(['A'], axis=1, inplace=True)
df.reset_index().drop(['level_0'], axis=1)
Out[197]:
index B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
在這里,我們將索引設置為A
列A
但不刪除它,然后使用arange
函數重新索引 df。
很久以前就有人問過這個問題,但我有一個值得一提的簡單解決方案。 您可以簡單地使用 NumPy 的 NaN。 例如:
import numpy as np
df[i,j] = np.NaN
會做的伎倆。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.