2013-04-04 35 views
7

Pandaları ana Trace (MCMC'den parametre uzayı dizisi) nesnesi olarak kullanmayı umuyorum.Çok dilli dizilerin pandalarda saklanması DataFrame sütunları

Pandalarda saklamak istediğim string-> array dizilerinin bir listesi var. Dicts'deki tuşlar her zaman aynıdır ve her anahtar için numpy dizisinin şekli her zaman aynıdır, ancak şekil farklı anahtarlar için farklı olabilir ve farklı boyutlarda olabilir.

0dkullanıyordum, 1d değerleri için iyi çalışıyor gibi görünüyor, ancak nd> 1 değerleri için pandalar değerleri güzel çizim ve diğer güzel şeylere izin vermeyen nesneler olarak saklar. Daha iyi davranışlar elde etme konusunda herhangi bir öneriniz var mı?

Örnek veri

point = {'x': array(-0.47652306228698005), 
     'y': array([[-0.41809043], 
        [ 0.48407823]])} 

points = 10 * [ point] 

Ben

df = DataFrame(points) 

veya

df = DataFrame() 
df.append(points, ignore_index=True) 

böyle bir şey yapmak ve var edebilmek istiyorum

>> df['x'][1].shape 
() 
>> df['y'][1].shape 
(2,1) 
+1

[Panel] (http://pandas.pydata.org/pandas-docs/dev/dsintro.html#panel) veri yapısına baktınız mı? Kullanım durumunuzla yardımcı olduğundan emin değilsiniz ... –

+1

Sorunuz için örnek veriler alabilir miyiz? – BKay

+0

Kesinlikle, biraz yukarıda ekledim. Bu yardımcı olur mu? Yoksa daha fazlasını ister misiniz? –

cevap

3

Bu, Pandalar'ın felsefesine karşı, bir boyutlu veri yapısı olarak Series'u görüyor gibi görünüyor. Bu nedenle, Series el ile oluşturmalısınız, veri türü "object" olduklarını söyleyin. Bu, herhangi bir otomatik veri dönüşümünü uygulamamanız anlamına gelir.

Bu (yeniden sıralanmış ipython oturumu) gibi yapabilirsiniz:

In [9]: import pandas as pd 

In [1]: point = {'x': array(-0.47652306228698005), 
    ...:   'y': array([[-0.41809043], 
    ...:      [ 0.48407823]])} 

In [2]: points = 10 * [ point] 

In [5]: lx = [p["x"] for p in points] 

In [7]: ly = [p["y"] for p in points] 

In [40]: sx = pd.Series(lx, dtype=numpy.dtype("object")) 

In [38]: sy = pd.Series(ly, dtype=numpy.dtype("object")) 

In [43]: df = pd.DataFrame({"x":sx, "y":sy}) 

In [45]: df['x'][1].shape 
Out[45]:() 

In [46]: df['y'][1].shape 
Out[46]: (2, 1) 
+1

Bu durumun açık olmadığını biliyorum. Bence df.append (points) yöntemi temelde bunu yapacak. –

+0

@JohnSalvatier haklı! – hobs

7

nispeten yeni kütüphane xray [1] sormak tam olarak ne yapmak Dataset ve DataArray yapıları vardır.İşte

bir ipython oturum olarak yazılı sorununuza almak benim şöyledir:

>>> import numpy as np 
>>> import xray 

>>> ## Prepare data: 
>>> # 
>>> point = {'x': np.array(-0.47652306228698005), 
...   'y': np.array([[-0.41809043], 
...      [ 0.48407823]])} 
>>> points = 10 * [point] 

>>> ## Convert to Xray DataArrays: 
>>> # 
>>> list_x = [p['x'] for p in points] 
>>> list_y = [p['y'] for p in points] 
>>> da_x = xray.DataArray(list_x, [('x', range(len(list_x)))]) 
>>> da_y = xray.DataArray(list_y, [ 
...  ('x', range(len(list_y))), 
...  ('y0', range(2)), 
...  ('y1', [0]), 
... ]) 

Bunlar şimdiye kadar inşa edilmiş iki DataArray örnekleri şunlardır:

>>> print(da_x) 
<xray.DataArray (x: 10)> 
array([-0.47652306, -0.47652306, -0.47652306, -0.47652306, -0.47652306, 
     -0.47652306, -0.47652306, -0.47652306, -0.47652306, -0.47652306]) 
Coordinates: 
    * x  (x) int32 0 1 2 3 4 5 6 7 8 9 


>>> print(da_y.T) ## Transposed, to save lines. 
<xray.DataArray (y1: 1, y0: 2, x: 10)> 
array([[[-0.41809043, -0.41809043, -0.41809043, -0.41809043, -0.41809043, 
     -0.41809043, -0.41809043, -0.41809043, -0.41809043, -0.41809043], 
     [ 0.48407823, 0.48407823, 0.48407823, 0.48407823, 0.48407823, 
      0.48407823, 0.48407823, 0.48407823, 0.48407823, 0.48407823]]]) 
Coordinates: 
    * x  (x) int32 0 1 2 3 4 5 6 7 8 9 
    * y0  (y0) int32 0 1 
    * y1  (y1) int32 0 

Şimdi birleştirebilirsiniz Bu iki DataArray, ortak x boyutunda bir DataSet:

>>> ds = xray.Dataset({'X':da_x, 'Y':da_y}) 
>>> print(ds) 
<xray.Dataset> 
Dimensions: (x: 10, y0: 2, y1: 1) 
Coordinates: 
    * x  (x) int32 0 1 2 3 4 5 6 7 8 9 
    * y0  (y0) int32 0 1 
    * y1  (y1) int32 0 
Data variables: 
    X  (x) float64 -0.4765 -0.4765 -0.4765 -0.4765 -0.4765 -0.4765 -0.4765 ... 
    Y  (x, y0, y1) float64 -0.4181 0.4841 -0.4181 0.4841 -0.4181 0.4841 -0.4181 ... 

Ve nihayet istediği şekilde erişmek ve birleştirilmiş veriler edebilirsiniz:

>>> ds['X'].sum() 
<xray.DataArray 'X'()> 
array(-4.765230622869801) 


>>> ds['Y'].sum() 
<xray.DataArray 'Y'()> 
array(0.659878) 


>>> ds['Y'].sum(axis=1) 
<xray.DataArray 'Y' (x: 10, y1: 1)> 
array([[ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878], 
     [ 0.0659878]]) 
Coordinates: 
    * x  (x) int32 0 1 2 3 4 5 6 7 8 9 
    * y1  (y1) int32 0 

>>> np.all(ds['Y'].sum(axis=1) == ds['Y'].sum(dim='y0')) 
True 

>>>> ds['X'].sum(dim='y0') 
Traceback (most recent call last): 
ValueError: 'y0' not found in array dimensions ('x',) 

[1] pandalar gibi etiketleri ile N boyutlu verileri işlemek için bir kütüphane 2D için yapar: http://xray.readthedocs.org/en/stable/data-structures.html#dataset

2

Eike en answer @ ve JohnSalvatier yorumuna @ birleştiren Pandasonic güzel görünüyor:

>>> import pandas as pd 
>>> np = pandas.np 
>>> point = {'x': np.array(-0.47652306228698005), 
... ...:   'y': np.array([[-0.41809043], 
... ...:      [ 0.48407823]])} 
>>> points = 10 * [ point] 
>>> df = pd.DataFrame().append(points) 
>>> df.x 
# 0 -0.476523062287 
# ... 
# 9 -0.476523062287 
# Name: x, dtype: object 
>>> df.y 
# 0 [[-0.41809043], [0.48407823]] 
# ... 
# 9 [[-0.41809043], [0.48407823]] 
# Name: y, dtype: object 
>>> df.y[0] 
# array([[-0.41809043], 
#  [ 0.48407823]]) 
>>> df.y[0].shape 
# (2, 1) 

hala manuel bir DataFrame geri Dizilerin sütunu dönüştürmek zorunda çizmek (ve tüm diğer serin 2-B Pandalar şeyler yapmak) için:

>>> dfy = pd.DataFrame([row.T[0] for row in df2.y]) 
>>> dfy += np.matrix([[0] * 10, range(10)]).T 
>>> dfy *= np.matrix([range(10), range(10)]).T 
>>> dfy.plot() 

example 2-D plot

diskte saklamak için, kullanım to_pickle:

>>> df.to_pickle('/tmp/sotest.pickle') 
>>> df2 = pd.read_pickle('/tmp/sotest.pickle') 
>>> df.y[0].shape 
# (2, 1) 

Eğer np.array s nesneler dizeleri haline to_csv kullanıyorsanız:

>>> df.to_csv('/tmp/sotest.csv') 
>>> df2 = pd.DataFrame.from_csv('/tmp/sotest.csv') 
>>> df2.y[0] 
# '[[-0.41809043]\n [ 0.48407823]]' 
İlgili konular