與apply
創建新行與過濾,然後分配新的列名
df1 = df.apply(lambda x: pd.Series(x[x!=0].values), 1).fillna(0).astype(int)
df1.columns = df.columns.tolist()[:len(df1.columns)]
df1 = df1.reindex(columns=df.columns, fill_value=0)
print (df1)
yearStart 2014 2015 2016 2017 2018 2019
0 2015 150 200 0 0 0 0
1 2016 200 140 35 10 0 0
2 2017 20 12 12 0 0 0
如果更大的數據幀是可能使用Divakar功能justify_rows
:
def justify_rows(a, side='left'):
mask = a>0
justified_mask = np.sort(mask,1)
if side=='left':
justified_mask = justified_mask[:,::-1]
out = np.zeros_like(a)
out[justified_mask] = a[mask]
return out
df1 = pd.DataFrame(justify_rows(df.values), columns=df.columns, index=df.index)
print (df1)
yearStart 2014 2015 2016 2017 2018 2019
0 2015 150 200 0 0 0 0
1 2016 200 140 35 10 0 0
2 2017 20 12 12 0 0 0
如果w螞蟻字符串Years
:
cols = ['yearStart'] + ['Year+{}'.format(x) for x in range(len(df.columns) - 1)]
df1 = pd.DataFrame(justify_rows(df.values), columns=cols, index=df.index)
print (df1)
yearStart Year+0 Year+1 Year+2 Year+3 Year+4 Year+5
0 2015 150 200 0 0 0 0
1 2016 200 140 35 10 0 0
2 2017 20 12 12 0 0 0
編輯:
對於第二溶液需要this solution用於選擇第一連續0
:
def justify_rows(a, side='left'):
mask = a.cumsum(axis=1) != 0
print (mask)
justified_mask = np.sort(mask,1)
print (justified_mask)
if side=='left':
justified_mask = justified_mask[:,::-1]
out = np.zeros_like(a)
out[justified_mask] = a[mask]
print (out)
return out
cols = ['Year+{}'.format(x) for x in range(len(df.columns) - 1)]
df1 = df[['yearStart']].join(pd.DataFrame(justify_rows(df.values[:, 1:]),
columns=cols, index=df.index))
print (df1)
yearStart Year+0 Year+1 Year+2 Year+3 Year+4 Year+5
0 2015 150 200 0 13 0 0
1 2016 200 140 35 0 0 0
2 2017 20 12 0 0 0 0
我通過你的修改相關更改答案。 – jezrael
關於我更新的問題,它完美的工作(128秒重塑200 000 * 4的數據幀)我用系列的掩碼語法來製作它(感謝Zero和Jarad)。 一個有趣的事實是:當我用apply()方法檢查每一行的'print()'時,我注意到第一行顯示兩次,即使對最終結果沒有影響 – phil
如果我或其他答案是有幫助的,不要忘記[接受](http://meta.stackexchange.com/a/5235/295067)它 - 點擊答案旁邊的複選標記('✓')將其從灰色變爲填充。 謝謝。 – jezrael