2016-07-22 14 views
3

Mit Pandas first_valid_index(), um Index der ersten Nicht-Null-Wert einer Spalte zu erhalten, wie kann ich einzelnen Wert der Spalte anstelle der gesamten Spalte verschieben. das heißtWie man einzelnen Wert einer Pandas Dataframe Spalte verschiebt

data = {'year': [2010, 2011, 2012, 2013, 2014, 2015, 2016,2017, 2018, 2019], 
     'columnA': [10, 21, 20, 10, 39, 30, 31,45, 23, 56], 
     'columnB': [None, None, None, 10, 39, 30, 31,45, 23, 56], 
     'total': [100, 200, 300, 400, 500, 600, 700,800, 900, 1000]} 

df = pd.DataFrame(data) 
df = df.set_index('year') 
print df 
     columnA columnB total 
year       
2010  10  NaN 100 
2011  21  NaN 200 
2012  20  NaN 300 
2013  10  10 400 
2014  39  39 500 
2015  30  30 600 
2016  31  31 700 
2017  45  45 800 
2018  23  23 900 
2019  56  56 1000 

for col in df.columns: 
    if col not in ['total']: 
     idx = df[col].first_valid_index() 
     df.loc[idx, col] = df.loc[idx, col] + df.loc[idx, 'total'].shift(1) 

print df  

AttributeError: 'numpy.float64' object has no attribute 'shift' 

gewünschte Ergebnis:

print df 
     columnA columnB total 
year       
2010  10  NaN 100 
2011  21  NaN 200 
2012  20  NaN 300 
2013  10  310 400 
2014  39  39 500 
2015  30  30 600 
2016  31  31 700 
2017  45  45 800 
2018  23  23 900 
2019  56  56 1000 

Antwort

1

Sie können alle Spaltennamen filtern, wo mindestens ein NaN Wert und dann union mit Spalte verwenden total:

for col in df.columns: 
    if col not in pd.Index(['total']).union(df.columns[~df.isnull().any()]): 
     idx = df[col].first_valid_index() 
     df.loc[idx, col] += df.total.shift().loc[idx] 
print (df) 
     columnA columnB total 
year       
2010  10  NaN 100 
2011  21  NaN 200 
2012  20  NaN 300 
2013  10 310.0 400 
2014  39  39.0 500 
2015  30  30.0 600 
2016  31  31.0 700 
2017  45  45.0 800 
2018  23  23.0 900 
2019  56  56.0 1000 
+0

Ist die Spalte "Total" immer gültig? – jezrael

+0

Oder besser, ist möglich, wenn in der Spalte "Total" sind "NaN" -Werte? – jezrael

+0

ja, insgesamt kann NaN-Werte haben – ArchieTiger

2

ist das, was Sie wollen?

In [63]: idx = df.columnB.first_valid_index() 

In [64]: df.loc[idx, 'columnB'] += df.total.shift().loc[idx] 

In [65]: df 
Out[65]: 
     columnA columnB total 
year 
2010  10  NaN 100 
2011  21  NaN 200 
2012  20  NaN 300 
2013  10 310.0 400 
2014  39  39.0 500 
2015  30  30.0 600 
2016  31  31.0 700 
2017  45  45.0 800 
2018  23  23.0 900 
2019  56  56.0 1000 

UPDATE: ab Pandas 0.20.1 the .ix indexer is deprecated, in favor of the more strict .iloc and .loc indexers.

+0

ja, aber ich 'nan' für' columnA' – ArchieTiger

+0

'für col in df.columns : wenn col nicht in ['total']: idx = df [Spalte] .first_valid_index() Drucken df.ix [idx, col] + df.total.shift(). Ix [idx] ' – ArchieTiger

+0

@ArchieTiger , warum benutzt du die for-Schleife? – Merlin

Verwandte Themen