web-dev-qa-db-ja.com

pandasで、Int64を標準のint64ではなくデフォルトの整数dtypeにする

コンストラクターオーバーロードのいずれかから構築されているかどうか、.read_csv().read_xlsx().read_sql()から派生したものかどうかに関係なく、すべてのデータフレームが必要です。メソッドは、新しいnullable Int64datatypeint64ではなく、すべての整数のデフォルトdtypeとして使用します。

DataFrameクラスまたはSeriesクラスのサブクラス化、メソッドやコンストラクター属性の再実装など、「良い」方法がない場合は、文字通りあらゆるレベルの狂気にこれを行うつもりです。

私の質問は、これは可能ですか?その場合、どうすればよいですか?

17
matthewgdv

私は自分のお金をサルのパッチに当てます。最も簡単な方法は、DataFrameコンストラクタにモンキーパッチを適用することです。これは次のようになります。

import pandas
pandas.DataFrame.__old__init__ = pandas.DataFrame.__init__
def new_init(self, data=None, index=None, columns=None, dtype=pd.Int64Dtype(), copy=False):
    self.__old__init__(data=data, index=index, columns=None, dtype=dtype, copy=copy)

pandas.DataFrame.__init__ = new_init

もちろん、あなたは世界を壊す危険を冒します。幸運を!

2
Joel

次のような関数を使用できます。

_def nan_ints(df,convert_strings=False,subset = None):
    types = ['int64','float64']
    if subset is None:
        subset = list(df)
    if convert_strings:
        types.append('object')
    for col in subset:
        try:
            if df[col].dtype in types:
                df[col] = df[col].astype(float).astype('Int64')
        except:
            pass
    return df
_

各列を反復処理し、それがintの場合はInt64に変換します。 floatの場合、列のすべての値がNaN以外のintに変換できる場合にのみ、Int64に変換されます。 convert_strings引数を使用して、文字列をInt64に変換するオプションも提供しました。

_df1 = pd.DataFrame({'a':[1.1,2,3,1],
                  'b':[1,2,3,np.nan],
                  'c':['1','2','3',np.nan],
                  'd':[3,2,1,np.nan]})


nan_ints(df1,convert_strings=True,subset=['b','c'])
df1.info()

_

以下を返します:

_<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
a    4 non-null float64
b    3 non-null Int64
c    3 non-null Int64
d    3 non-null float64
dtypes: Int64(2), float64(2)
memory usage: 216.0 bytes
_

これをすべてのDataFrameで使用する場合は、関数をモジュールに追加して、パンダを使用するたびにインポートすることができます。 _from my_module import nan_ints_次に、次のように使用します:nan_ints(pd.read_csv(path))

注:Nullable integerデータ型はバージョン0.24.0で新しく追加されました。これが documentation です。

2
braintho