2017-02-18 5 views
1

私は選択された行全体を合計すると異常な動作を示すいくつかのWebデータ(テニスゲーム用)からコンパイルされたpandas DataFrameを持っています。奇妙なpandas.DataFrame.sum(軸= 1)の動作

DataFrame: 
In [178]: tdf.shape 
Out[178]: (47028, 57) 

In [201]: cols 
Out[201]: ['L1', 'L2', 'L3', 'L4', 'L5', 'W1', 'W2', 'W3', 'W4', 'W5'] 

In [177]: tdf[cols].head() 
Out[177]: 
L1 L2 L3 L4 L5 W1 W2 W3 W4 W5 
0 4.0 2 NaN NaN NaN 6.0 6 NaN NaN NaN 
1 3.0 3 NaN NaN NaN 6.0 6 NaN NaN NaN 
2 7.0 5 3 NaN NaN 6.0 7 6 NaN NaN 
3 1.0 4 NaN NaN NaN 6.0 6 NaN NaN NaN 
4 6.0 7 4 NaN NaN 7.0 5 6 NaN NaN 

tdf[cols].sum(axis=1)を使用して行全体の合計を計算しようとすると、問題は、ときに私がいるため、特定のレコード(行13771)に起因すると思わ

In [180]: tdf[cols].sum(axis=1).head() 
Out[180]: 
0 10.0 
1  9.0 
2 13.0 
3  7.0 
4 13.0 
dtype: float64 

:以下のように、上記の表から、第一の行の合計は18.0する必要がありますが、それを10として報告されますこの行を除外し、合計が正しく計算されます。

In [182]: tdf.iloc[:13771][cols].sum(axis=1).head() 
Out[182]: 
0 18.0 
1 18.0 
2 34.0 
3 17.0 
4 35.0 
dtype: float64 

それを含め、一方:

In [183]: tdf.iloc[:13772][cols].sum(axis=1).head() 
Out[183]: 
0 10.0 
1  9.0 
2 13.0 
3  7.0 
4 13.0 
dtype: float64 

は列全体に対して間違った結果を提供します。

次のように問題の記録は次のとおりです。

In [196]: tdf[cols].iloc[13771] 
Out[196]: 
L1  1 
L2  1 
L3 NaN 
L4 NaN 
L5 NaN 
W1  6 
W2  0 
W3 
W4 NaN 
W5 NaN 
Name: 13771, dtype: object 

In [197]: tdf[cols].iloc[13771].W3 
Out[197]: ' ' 

In [198]: type(tdf[cols].iloc[13771].W3) 
Out[198]: str 

私は次のバージョン実行しているよ。確かに、単一の悪いフォーマットされたレコードは他のレコードの合計に影響を与えるべきではありません

In [192]: sys.version 
Out[192]: '3.4.3 (default, Nov 17 2016, 01:08:31) \n[GCC 4.8.4]' 
In [193]: pd.__version__ 
Out[193]: '0.19.2' 
In [194]: np.__version__ 
Out[194]: '1.12.0' 

を?これはバグですか、何か間違っていますか?

大変助けてください!

答えて

0

問題empty stringである - その列W3dtypeobjectである(明らかstring)とsumはそれを省略します。

ソリューション:

NaNに問題empty string値を交換し、その後float

tdf.loc[13771, 'W3'] = np.nan 

tdf.W3 = tdf.W3.astype(float) 

またはサブセットcolsNaNに、すべての空の文字列を置き換えてみてくださいにキャストしてみてください。

tdf[cols] = tdf[cols].replace({'':np.nan}) 
#if necessary 
tdf[cols] = tdf[cols].astype(float) 

別の解決策問題のある用途ではto_numericですC列 - NaNにすべての非数値に置き換えます。

tdf.W3 = pd.to_numerice(tdf.W3, erors='coerce') 

それとも一般の列colsに適用されます:ポインター&迅速な返信用

tdf[cols] = tdf[cols].apply(lambda x: pd.to_numeric(x, errors='coerce')) 
+0

感謝を。 'to_numeric'を適用すると、そのトリックが実行されます。しかし、文字列の記録に黙って失敗したという事実は望ましくないようです。私はこれで行くだろう。 – Muchadoaboutnothing