Fügen Sie ein Feld in pandas dataframe mit MultiIndex-Spalten hinzu

Ich habe nach einer Antwort auf diese Frage gesucht, da sie ziemlich einfach zu sein scheint, aber noch nichts gefunden habe. Entschuldigung, wenn ich etwas verpasst habe. Ich habe Pandas Version 0.10.0 und habe mit Daten der folgenden Form experimentiert:

import pandas
import numpy as np
import datetime
start_date = datetime.datetime(2009,3,1,6,29,59)
r = pandas.date_range(start_date, periods=12)
cols_1 = ['AAPL', 'AAPL', 'GOOG', 'GOOG', 'GS', 'GS']
cols_2 = ['close', 'rate', 'close', 'rate', 'close', 'rate']
dat = np.random.randn(12, 6)
cols = pandas.MultiIndex.from_arrays([cols_1, cols_2], names=['ticker','field'])
dftst = pandas.DataFrame(dat, columns=cols, index=r)
print dftst



ticker                   AAPL                GOOG                  GS          
field                   close      rate     close      rate     close      rate
2009-03-01 06:29:59  1.956255 -2.074371 -0.200568  0.759772 -0.951543  0.514577
2009-03-02 06:29:59  0.069611 -2.684352 -0.310006  0.730205 -0.302949 -0.830452
2009-03-03 06:29:59  2.077130 -0.903784  0.449857 -1.357464 -0.469572 -0.008757
2009-03-04 06:29:59  1.585358 -2.063672  0.600889 -1.741606 -0.299875  0.565253
2009-03-05 06:29:59  0.269123  0.226593  1.132663  0.485035  0.796858 -0.423112
2009-03-06 06:29:59  0.094879 -1.040069  0.613450 -0.175266 -0.065172  3.374658
2009-03-07 06:29:59 -1.255167 -0.326474  0.437053 -0.231594  0.437703 -0.256811
2009-03-08 06:29:59  0.115454 -1.096841 -1.189211 -0.208098 -0.807860  0.158198
2009-03-09 06:29:59  2.142816  0.173878 -0.160932  0.367309 -0.449765 -0.325400
2009-03-10 06:29:59  0.470669 -0.346805  1.152648  0.844632  1.031602 -0.012502
2009-03-11 06:29:59 -1.366954  0.452177  0.010713 -1.331553  0.226781  0.456900
2009-03-12 06:29:59  2.182409  0.890023 -0.627318 -1.516574 -1.565416 -0.694320

Wie Sie sehen, versuche ich, 3D-Zeitreihendaten darzustellen. Ich habe also einen Timeseries-Index und MultiIndex-Spalten. Ich bin mit dem Schneiden der Daten ziemlich bequem. Wenn ich nur einen nachgestellten Mittelwert der Abschlussdaten haben möchte, kann ich Folgendes tun:

pandas.rolling_mean(dftst.ix[:,::2], 5)


ticker                   AAPL      GOOG        GS
field                   close     close     close
2009-03-01 06:29:59       NaN       NaN       NaN
2009-03-02 06:29:59       NaN       NaN       NaN
2009-03-03 06:29:59       NaN       NaN       NaN
2009-03-04 06:29:59       NaN       NaN       NaN
2009-03-05 06:29:59  0.410966 -0.412356  0.722951
2009-03-06 06:29:59 -0.103187 -0.497165  0.137731
2009-03-07 06:29:59  0.000194 -0.645375 -0.298504
2009-03-08 06:29:59 -0.074036 -0.541717 -0.035906
2009-03-09 06:29:59 -0.391863 -0.671918 -0.554380
2009-03-10 06:29:59 -0.336397 -0.411845 -0.992615
2009-03-11 06:29:59 -0.251645 -0.289512 -0.458246
2009-03-12 06:29:59 -0.138925  0.244572 -0.230743

Was ich nicht tun kann, ist ein neues Feld wie avg_close zu erstellen und ihm zuzuweisen. Im Idealfall würde ich gerne Folgendes tun:

dftst [:, 'avg_close'] = pandas.rolling_mean (dftst.ix [:, :: 2], 5)

Selbst wenn ich die Level meines MultiIndex vertausche, kann ich es nicht zum Laufen bringen:

dftst = dftst.swaplevel(1,0,axis=1)
print dftst['close']

ticker                   AAPL      GOOG        GS
2009-03-01 06:29:59  1.178557 -0.505672 -0.336645
2009-03-02 06:29:59  0.234305  0.581429 -0.232252
2009-03-03 06:29:59 -0.734798  0.117810  1.658418
2009-03-04 06:29:59 -1.555033 -0.298322  0.127408
2009-03-05 06:29:59  0.244102 -1.030041 -0.562039
2009-03-06 06:29:59 -0.297454  1.150564 -1.930883
2009-03-07 06:29:59  0.818910 -0.905296  1.219946
2009-03-08 06:29:59  0.586816  0.965242  0.928546
2009-03-09 06:29:59 -0.357693  0.071455  0.072956
2009-03-10 06:29:59  0.651803 -0.685937  0.805779
2009-03-11 06:29:59  0.569802 -0.062447 -1.349261
2009-03-12 06:29:59 -1.886335  0.205778 -0.864273

dftst['avg_close'] = pandas.rolling_mean(dftst['close'], 3)


----> 1 dftst['avg_close'] = pandas.rolling_mean(dftst['close'], 3)

/usr/local/lib/python2.7/dist-packages/pandas/core/frame.pyc in
__setitem__(self, key, value)    2041         else:    2042             # set column

-> 2043             self._set_item(key, value)    2044     2045     def _boolean_set(self, key, value):

/usr/local/lib/python2.7/dist-packages/pandas/core/frame.pyc in
_set_item(self, key, value)    2077         """    2078         value = self._sanitize_column(key, value)
-> 2079         NDFrame._set_item(self, key, value)    2080     2081     def insert(self, loc, column, value):

/usr/local/lib/python2.7/dist-packages/pandas/core/generic.pyc in
_set_item(self, key, value)
    544 
    545     def _set_item(self, key, value):
--> 546         self._data.set(key, value)
    547         self._clear_item_cache()
    548 

/usr/local/lib/python2.7/dist-packages/pandas/core/internals.pyc in set(self, item, value)
    951         except KeyError:
    952             # insert at end

--> 953             self.insert(len(self.items), item, value)
    954 
    955         self._known_consolidated = False

/usr/local/lib/python2.7/dist-packages/pandas/core/internals.pyc in insert(self, loc, item, value)
    963 
    964         # new block

--> 965         self._add_new_block(item, value, loc=loc)
    966 
    967         if len(self.blocks) > 100:

/usr/local/lib/python2.7/dist-packages/pandas/core/internals.pyc in
_add_new_block(self, item, value, loc)
    992             loc = self.items.get_loc(item)
    993         new_block = make_block(value, self.items[loc:loc+1].copy(),
--> 994                                self.items)
    995         self.blocks.append(new_block)
    996 

/usr/local/lib/python2.7/dist-packages/pandas/core/internals.pyc in make_block(values, items, ref_items)
    463         klass = ObjectBlock
    464 
--> 465     return klass(values, items, ref_items, ndim=values.ndim)
    466 
    467 # TODO: flexible with index=None and/or items=None


/usr/local/lib/python2.7/dist-packages/pandas/core/internals.pyc in
__init__(self, values, items, ref_items, ndim)
     30         if len(items) != len(values):
     31             raise AssertionError('Wrong number of items passed (%d vs %d)'
---> 32                                  % (len(items), len(values)))
     33 
     34         self._ref_locs = None

AssertionError: Wrong number of items passed (1 vs 3)

Wenn meine Spalten nicht MultiIndex wären, könnte ich Folgendes zuweisen:

start_date = datetime.datetime(2009,3,1,6,29,59)
r = pandas.date_range(start_date, periods=12)
cols = ['AAPL', 'GOOG', 'GS']
dat = np.random.randn(12, 3)
dftst2 = pandas.DataFrame(dat, columns=cols, index=r)
print dftst2

                         AAPL      GOOG        GS
2009-03-01 06:29:59  2.476787  2.386037 -0.777566
2009-03-02 06:29:59 -0.820647  1.006159 -0.590240
2009-03-03 06:29:59  0.433960  0.104458  0.282641
2009-03-04 06:29:59  0.300190 -0.300786 -1.780412
2009-03-05 06:29:59 -0.247919  1.616572  1.145594
2009-03-06 06:29:59 -0.779130  0.695256  0.845819
2009-03-07 06:29:59  0.572073  0.349394 -3.557776
2009-03-08 06:29:59  2.019885  0.358346  1.350812
2009-03-09 06:29:59  0.472328 -0.334223 -0.605862
2009-03-10 06:29:59 -1.570479  0.410808  0.616515
2009-03-11 06:29:59  1.177562 -0.240396 -2.126951
2009-03-12 06:29:59  0.311566 -1.743213  0.382617

Um ein Feld basierend auf einem anderen Feld hinzuzufügen, kann ich Folgendes tun:

dftst2['GOOG_avg'] = pandas.rolling_mean(dftst2['GOOG'], 3)
print dftst2


                         AAPL      GOOG        GS  GOOG_avg
2009-03-01 06:29:59  2.476787  2.386037 -0.777566       NaN
2009-03-02 06:29:59 -0.820647  1.006159 -0.590240       NaN
2009-03-03 06:29:59  0.433960  0.104458  0.282641  1.165551
2009-03-04 06:29:59  0.300190 -0.300786 -1.780412  0.269944
2009-03-05 06:29:59 -0.247919  1.616572  1.145594  0.473415
2009-03-06 06:29:59 -0.779130  0.695256  0.845819  0.670347
2009-03-07 06:29:59  0.572073  0.349394 -3.557776  0.887074
2009-03-08 06:29:59  2.019885  0.358346  1.350812  0.467666
2009-03-09 06:29:59  0.472328 -0.334223 -0.605862  0.124506
2009-03-10 06:29:59 -1.570479  0.410808  0.616515  0.144977
2009-03-11 06:29:59  1.177562 -0.240396 -2.126951 -0.054604
2009-03-12 06:29:59  0.311566 -1.743213  0.382617 -0.524267

Ich habe versucht, ein Panel-Objekt zu verwenden, habe aber bisher keine schnelle Möglichkeit gefunden, ein Feld mit MultiIndex-Spalten hinzuzufügen. Idealerweise würde die andere Ebene der Spalten übertragen. Ich entschuldige mich, wenn es andere Beiträge gegeben hat, die diese Frage beantworten. Anregungen wäre sehr dankbar.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage