2017-09-18 30 views
1

你好我处理一个数据帧象下面这样:熊猫数据框中:如何根据该行中的值在其他一些列复制

yearStart 2014 2015 2016 2017 2018 2019 
0 2015  0 150 200  0  0  0  
1 2016  0  0 200 140 35 10  
2 2017  0  0  0  20 12 12 

通常情况下,它是一个财务报告的所有费用,begining时在几年

yearStart Year+0 Year+1 Year+2 Year+3 Year+4 ... Year+N 
0  2015 150  200  0  0  0  
1  2016 200  140  35  0  0  
2  2017 20  12  12  0  0  

如何重塑数据帧,以具有存储在一个相对日期样式从合同的第一年DATAS合同签订(列“年开始”)和持久。

我试图通过iterrows()每行,而在另一个数据帧复制有关列,但它需要太多的时间...

编辑:

嗯,我忘了,也许一年的说合同的有关期限,价值为0,不应该被遗忘。要考虑的列是在yearStart和end之间的日期,作为参数给出。输入更像是这样的:

0 2015  0 150 200  0 13  0  
    1 2016  0  0 200 140 35  0 10 
    2 2017  0  0  0  20 12  0 12 

谢谢

+0

我通过你的修改相关更改答案。 – jezrael

+0

关于我更新的问题,它完美的工作(128秒重塑200 000 * 4的数据帧)我用系列的掩码语法来制作它(感谢Zero和Jarad)。 一个有趣的事实是:当我用apply()方法检查每一行的'print()'时,我注意到第一行显示两次,即使对最终结果没有影响 – phil

+0

如果我或其他答案是有帮助的,不要忘记[接受](http://meta.stackexchange.com/a/5235/295067)它 - 点击答案旁边的复选标记('✓')将其从灰色变为填充。 谢谢。 – jezrael

回答

1
df=df.replace({0:np.nan}) 
df=df.loc[:,df.isnull().sum(0).ne(3)] 

选项1:

df.apply(lambda x : (x[x.notnull()].values.tolist()+x[x.isnull()].values.tolist()),1).fillna(0) 

出[145]:

yearStart 2015 2016 2017 2018 2019 
0  2015.0 150.0 200.0 0.0 0.0 0.0 
1  2016.0 200.0 140.0 35.0 10.0 0.0 
2  2017.0 20.0 12.0 12.0 0.0 0.0 

选项2:

df.apply(lambda x: sorted(x, key=pd.isnull), 1).fillna(0) 


Out[145]: 
    yearStart 2015 2016 2017 2018 2019 
0  2015.0 150.0 200.0 0.0 0.0 0.0 
1  2016.0 200.0 140.0 35.0 10.0 0.0 
2  2017.0 20.0 12.0 12.0 0.0 0.0 
1

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 
+1

当你提到'Divakar函数justify_rows'时,你毫无疑问赢了:) – Wen

相关问题