web-dev-qa-db-ja.com

NumPyまたはPandas:NaN値を持ちながら配列型を整数として保持

内部にint64としてリストされた要素を保持したまま、numpy配列のデータ型をint(またはnumpy.NaNなど)に固定したままにする好ましい方法はありますか?

特に、社内のデータ構造をPandas DataFrameに変換しています。この構造には、NaNがまだある整数型の列があります(ただし、列のdtypeはintです)。これをDataFrameにすると、すべてをフロートとして再キャストするように見えますが、intになりたいのです。

考え?

試行したこと:

coerce_float=Falseでpandas.DataFrameの下でfrom_records()関数を使用しようとしましたが、これは役に立ちませんでした。また、Num fill_valueでNumPyマスク配列を使用しようとしましたが、これも機能しませんでした。これらすべてが原因で、列のデータ型が浮動小数点数になりました。

127
ely

この機能はpandas(バージョン0.24以降)に追加されました: https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html# optional-integer-na-support

この時点で、デフォルトのdtype int64(小文字)ではなく、拡張子dtype Int64(大文字)を使用する必要があります。

46
techvslife

NaNは整数配列に格納できません。これは、現時点でのpandasの既知の制限です。私はNumPyのNA値(RのNAと同様)の進展を待っていましたが、NumPyがこれらの機能を取得するまでに少なくとも6か月から1年かかります。

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(この機能はpandasのバージョン0.24から追加されましたが、デフォルトのdtype int64(小文字)ではなく、拡張子dtype Int64(大文字)を使用する必要があることに注意してください: https://pandas.pydata。 org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support

96
Wes McKinney

パフォーマンスが主な問題でない場合は、代わりに文字列を保存できます。

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

その後、NaNと必要なだけミックスできます。アプリケーションに応じて、本当に整数が必要な場合は、-1、または0、または1234567890、またはNaNを表す他の専用値を使用できます。

列を一時的に複製することもできます。もう1つはintまたは文字列を使用した実験的なものです。次に、合理的なすべての場所にassertsを挿入して、2つが同期していることを確認します。十分なテストの後、フロートを手放すことができます。

7
osa

これはすべての場合の解決策ではありませんが、私のもの(ゲノム座標)はNaNとして0を使用することに頼りました

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

これにより、少なくとも適切な「ネイティブ」列タイプを使用できるようになり、減算、比較などの操作は期待どおりに機能します

3
pufferfish

パンダv0.24 +

整数シリーズのNaNをサポートする機能は、v0.24以降で使用可能になります。 これに関する情報 はv0.24の「新機能」セクションにあり、詳細は Nullable Integer Data Type にあります。

パンダv0.23以前

一般に、float値を含めることでシリーズがintからfloatにアップキャストされる場合でも、可能な場合はNaNシリーズを使用するのが最善です。これにより、ベクトル化されたNumPyベースの計算が可能になります。そうでなければ、Pythonレベルのループが処理されます。

ドキュメントは suggest を行います:「1つの可能性は、代わりにdtype=object配列を使用することです。」例えば:

s = pd.Series([1, 2, 3, np.nan])

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object

美容上の理由から、例えばファイルへの出力の場合、これが望ましい場合があります

パンダv0.23以前:背景

NaNfloatと見なされます現在のドキュメント(v0.23現在) 整数シリーズがfloatにアップキャストされる理由を指定します。

NumPyにゼロから高性能のNAサポートが組み込まれていない場合、最大の犠牲は整数配列でNAを表現する能力です。

このトレードオフは、主にメモリとパフォーマンスの理由で行われ、結果のシリーズが引き続き「数値」であるようにします。

ドキュメントも ルールを提供するNaNを含めるためのアップキャスト用:

Typeclass   Promotion dtype for storing NAs
floating    no change
object      no change
integer     cast to float64
boolean     cast to object
2
jpp

pandas v 0.24.0であるため、これが可能になりました。

pandas 0.24.xリリースノート 引用: "Pandasは、欠損値を持つ整数dtypeを保持する機能を獲得しました。

1
mork

Float(1.143)ベクトルを整数(1)に変換しようとしている場合に追加したかったのですが、NAが新しい 'Int64' dtypeに変換するとエラーが発生します。これを解決するには、数値を丸めてから「.astype( 'Int64')」を実行する必要があります

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

私のユースケースは、intに丸めたいfloatシリーズがありますが、.round()を行うと、数字の末尾に「* .0」が残るため、末尾から0を削除できますintに変換します。