web-dev-qa-db-ja.com

Pandas列を文字列ではなく浮動小数点として解釈するデータフレーム

pandasデータフレームにcsvファイルをインポートしたい。IDを持つ列があり、すべての行にIDがあるわけではないが、数値のみで構成されている。

_   ID      xyz
0  12345     4.56
1           45.60
2  54231   987.00
_

この列を文字列として読み取りたいのですが、次のように指定しても

df=pd.read_csv(filename,dtype={'ID': str})

私は得る

_   ID         xyz
0  '12345.0'    4.56
1   NaN        45.60
2  '54231.0'  987.00
_

テーブルをインポートした後に文字列を編集する必要なしに、_'12345'_のような小数なしの文字列としてIDを取得する簡単な方法はありますか?

5
Georg B

解決策はこれですが、dfをインポートした後:

df = pd.read_csv(filename)
df['ID'] = df['ID'].astype(int).astype(str)

または、NaNがあるので:

df['ID'] = df['ID'].apply(lambda x: x if pd.isnull(x) else str(int(x)))
1
Joe

欠損値が数値列にない場合の考えられる解決策-広告パラメータkeep_default_na=False空の値を文字列に変換しませんが、すべてのデータでNaNに変換しないため、最初の列ではない場合もあります。 docs も確認してください:

import pandas as pd

temp=u"""ID;xyz
0;12345;4.56
1;;45.60
2;54231;987.00"""
#after testing replace 'pd.compat.StringIO(temp)' to 'filename.csv'
df = pd.read_csv(pd.compat.StringIO(temp), sep=";", dtype={'ID': str}, keep_default_na=False)
    print (df)
      ID     xyz
0  12345    4.56
1          45.60
2  54231  987.00

編集:

私にとってpandas 0.23.4あなたのソリューションを完全に機能させるので、それは低いバージョンのバグを意味しますpandasバージョン:

import pandas as pd

temp=u"""ID;xyz
0;12345;4.56
1;;45.60
2;54231;987.00"""
#after testing replace 'pd.compat.StringIO(temp)' to 'filename.csv'
df = pd.read_csv(pd.compat.StringIO(temp), sep=";", dtype={'ID': str})
print (df)
      ID     xyz
0  12345    4.56
1    NaN   45.60
2  54231  987.00
1
jezrael

Csvに書き込むときに浮動小数点形式を指定する

根本的な問題はデータをエクスポートするときの出力形式なので、操作は必要ありません。ただ使う:

df.to_csv('file.csv', float_format='%.0f')

特定の列だけにこの書式を設定したいので、 to_string

def format_int(x):
    return f'{x:.0f}' if x==x else ''

with open('file.csv', 'w') as fout:
    fout.write(df.to_string(formatters={'ID': format_int}))

数値データを数値に保つ

数字のみで構成されるIDの列があります

列に数値のみが含まれる場合、文字列に変換しないでください!文字列に変換したいという希望は XY問題 のようです。数値識別子は数値のままにする必要があります。

Float NaNプロンプトアップキャスト

あなたの問題は、NaN値がnumericシリーズの整数と共存できないことです。 NaNfloatであるため、Pandasは強制的にアップキャストします。object dtypeの代替は非効率的であり、推奨されないため、これは自然なことです。

実行可能な場合は、センチネル値を使用できます。 -1はnullを示します。

df['ID'] = pd.to_numeric(df['ID'], errors='coerce').fillna(-1).astype(int)

print(df)

      ID     xyz
0  12345    4.56
1     -1   45.60
2  54231  987.00
0
jpp