13

I've got a pandas dataframe with a column 'cap'. This column mostly consists of floats but has a few strings in it, for instance at index 2.

df =
    cap
0    5.2
1    na
2    2.2
3    7.6
4    7.5
5    3.0
...

I import my data from a csv file like so:

df = DataFrame(pd.read_csv(myfile.file))

Unfortunately, when I do this, the column 'cap' is imported entirely as strings. I would like floats to be identified as floats and strings as strings. Trying to convert this using:

df['cap'] = df['cap'].astype(float)

throws up an error:

could not convert string to float: na

Is there any way to make all the numbers into floats but keep the 'na' as a string?

4

4 に答える 4

21

(オブジェクトではなく) float64 dtype の列を使用した計算ははるかに効率的であるため、通常はこれが推奨されます...他の計算も行うことができます。このため、欠損データには (独自のプレースホルダーや None ではなく) NaN を使用することをお勧めします。

これは本当にあなたが望む答えですか?

In [11]: df.sum()  # all strings
Out[11]: 
cap    5.2na2.27.67.53.0
dtype: object

In [12]: df.apply(lambda f: to_number(f[0]), axis=1).sum()  # floats and 'na' strings
TypeError: unsupported operand type(s) for +: 'float' and 'str'

float に強制するには convert_numeric を使用する必要があります。

In [21]: df.convert_objects(convert_numeric=True)
Out[21]: 
   cap
0  5.2
1  NaN
2  2.2
3  7.6
4  7.5
5  3.0

または、NaN と見なされる値のリストに「na」を追加して、csv として直接読み取ります。

In [22]: pd.read_csv(myfile.file, na_values=['na'])
Out[22]: 
   cap
0  5.2
1  NaN
2  2.2
3  7.6
4  7.5
5  3.0

どちらの場合でも、sum (および他の多くの pandas 関数) が機能するようになりました。

In [23]: df.sum()
Out[23]:
cap    25.5
dtype: float64

ジェフがアドバイスするように:

高速で 3 回繰り返します: object==bad、float==good

于 2013-11-08T18:40:05.623 に答える
2

まず第一に、CSV をインポートする方法は冗長です。

df = DataFrame(pd.read_csv(myfile.file))

直接行うことができます:

df = pd.read_csv(myfile.file)

次に、float に変換し、数値以外を NaN として置きます。

df = pd.to_numeric(df, errors='coerce')
于 2018-01-30T04:48:00.527 に答える
1

ここに考えられる回避策があります

最初に、必要な場合にのみ数値を float に変換する関数を定義します。

 def to_number(s):
    try:
        s1 = float(s)
        return s1
    except ValueError:
        return s

そして、それを行ごとに適用します。


例:

与えられた

 df 
     0
  0  a
  1  2

aとの両方2が文字列の場合、次の方法で変換を行います

converted = df.apply(lambda f : to_number(f[0]) , axis = 1)  

 converted
 0    a
 1    2

タイプの直接チェック:

type(converted.iloc[0])                                                                                                                             
str

type(converted.iloc[1])                                                                                                                             
float
于 2013-11-08T16:51:51.700 に答える