2017-02-25 12 views
1

パンダで単純な異種データフレームを作成すると、各行に個別にアクセスするとデータ型が変わる理由を説明できます。Pandasなぜ私の列のデータ型が変わるのですか?

scene_df = pd.DataFrame({ 
    'magnitude': np.random.uniform(0.1, 0.3, (10,)), 
    'x-center': np.random.uniform(-1, 1, (10,)), 
    'y-center': np.random.uniform(-1, 1, (10,)), 
    'label': np.random.randint(2, size=(10,), dtype='u1')}) 

scene_df.dtypes 

プリント:

label   uint8 
magnitude float64 
x-center  float64 
y-center  float64 
dtype: object 

が、私は、行繰り返すとき:

[r['label'].dtype for i, r in scene_df.iterrows()] 

私が手をラベル

[dtype('float64'), 
dtype('float64'), 
dtype('float64'), 
dtype('float64'), 
dtype('float64'), 
... 

編集のためのfloat

が、私はこれを行うことを計画していたものに答えるために:

このコードの醜い部分として終わる
def square(mag, x, y): 
    wh = np.array([mag, mag]) 
    pos = np.array((x, y)) - wh/2 
    return plt.Rectangle(pos, *wh) 

def circle(mag, x, y): 
    return plt.Circle((x, y), mag) 

shape_fn_lookup = [square, circle] 

:私はプロットかもしれ円や四角の束を与える

[shape_fn_lookup[int(s['label'])](
     *s[['magnitude', 'x-center', 'y-center']]) 
for i, s in scene_df.iterrows()] 

[<matplotlib.patches.Circle at 0x7fcf3ea00d30>, 
<matplotlib.patches.Circle at 0x7fcf3ea00f60>, 
<matplotlib.patches.Rectangle at 0x7fcf3eb4da90>, 
<matplotlib.patches.Circle at 0x7fcf3eb4d908>, 
... 
] 

でもDataFrame.to_dict('records')このデータ型変換を行います。

type(scene_df.to_dict('records')[0]['label']) 

答えて

1

私はitertuples代わりのinterrowsを使用することをお勧めiterrowsは、各行ごとにシリーズを返すため、それは全体のdtypesを保存しません行(dtypeはDataFramesの列間で保持されます)。

[type(r.label) for r in scene_df.itertuples()] 

出力:

[numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8, 
numpy.uint8] 
+0

はい、これは私のユースケースの方がはるかにいいです:'[shape_fn_lookup [s](* rest)for i、s、* rest in scene_df。 itertuples()] ' –

1

iterrows()は、各行の列名からなるインデックスを持つ系列を返します。

Pandas.Seriesそれはfloat64にdowncastedされますので、一つだけDTYPEがあります

In [163]: first_row = list(scene_df.iterrows())[0][1] 

In [164]: first_row 
Out[164]: 
label  0.000000 
magnitude 0.293681 
x-center -0.628142 
y-center -0.218315 
Name: 0, dtype: float64 # <--------- NOTE 

In [165]: type(first_row) 
Out[165]: pandas.core.series.Series 

In [158]: [(type(r), r.dtype) for i, r in scene_df.iterrows()] 
Out[158]: 
[(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64')), 
(pandas.core.series.Series, dtype('float64'))] 
+0

だから、ダウンキャストを回避するためのいずれかの賢明な方法はありますか? –

+0

'int'は情報を失うことなく' float'として表現できますが、その逆もありません。私は上記のようにPandas.Seriesは単一の 'dtype'を持っている必要があります – MaxU

+0

@FrankWilson、それはあなたがそのループで何をしたいかによって決まります... – MaxU

関連する問題