2016-10-20 53 views
1

我試圖找到每行的DataFrame 中第一個有效值和最後一個有效值之間的差異。計算每行DataFrame中第一個有效值和最後一個有效值之間的差異?

我有一個for循環的工作代碼,並尋找更快的東西。 下面是我在做什麼目前一個例子:

import pandas as pd 
import numpy as np 

df = pd.DataFrame(
    np.arange(16).astype(np.float).reshape(4, 4), 
    columns=['a', 'b', 'c', 'd']) 
# Fill some NaN 
df.loc[0, ['a', 'd']] = np.nan 
df.loc[1, ['c', 'd']] = np.nan 
df.loc[2, 'b'] = np.nan 
df.loc[3, :] = np.nan 

print(df) 
# a b  c  d 
# 0 NaN 1.0 2.0 NaN 
# 1 4.0 5.0 NaN NaN 
# 2 8.0 NaN 10.0 11.0 
# 3 NaN NaN NaN NaN 

diffs = pd.Series(index=df.index) 
for i in df.index: 
    row = df.loc[i] 
    min_i = row.first_valid_index() 
    max_i = row.last_valid_index() 
    if min_i is None or min_i == max_i: # 0 or 1 valid values 
     continue 
    diffs[i] = df.loc[i, max_i] - df.loc[i, min_i] 

df['diff'] = diffs 
print(df) 

# a b  c  d diff 
# 0 NaN 1.0 2.0 NaN 1.0 
# 1 4.0 5.0 NaN NaN 1.0 
# 2 8.0 NaN 10.0 11.0 3.0 
# 3 NaN NaN NaN NaN NaN 

回答

3

一種方法是back and forward fill缺少的值,然後只是比較的第一行和最後一行。

df2 = df.fillna(method='ffill', axis=1).fillna(method='bfill', axis=1) 
df['diff'] = df2.ix[:, -1] - df2.ix[:, 0] 

如果你想這樣做在同一行,而無需創建一個新的數據框:

df['diff'] = df.fillna(method='ffill', axis=1).fillna(method='bfill', axis=1).apply(lambda r: r.d - r.a, axis=1) 
+1

ffill和bfill有軸參數,所以我想你可以做同樣沒有轉置。 ('df.ffill(axis = 1).bfill(axis = 1)') – ayhan

+0

真@ayhan!我很習慣在另一個軸上做它,我錯過了它。納入答案。 – ASGM

1

大熊貓讓您的生活輕鬆,一個方法(first_valid_values())一次。請注意,您必須刪除有所有 NaN值(在反正有沒有這點),任何行:

對於第一個有效值:

a= [df.ix[x,i] for x,i in enumerate(df.apply(lambda row: row.first_valid_index(), axis=1))] 

對於最後的有效值:

b = [df.ix[x,i] for x,i in enumerate(df.apply(lambda row: row[::-1].first_valid_index(), axis=1))] 

減去得到最終結果:

a-b 
相關問題