2016-11-20 2 views
1
パンダのために置き換える条件

I以下のパンダはDataFrame持っている:データフレーム

ID COL1 COL2 
123 1  ABC 
123 1  CCC 
123 1  AVV 
345 2  FGG 
345 2  FRG 
345 2  FGT 

ID COL1 COL2 
123 1  ABC 
123 1  CCC 
123 NaN AVV 
345 2  FGG 
345 NaN FRG 
345 NaN FGT 

私はこの結果を得るために同じIDに基づいてCol1内のすべてのNaN値を代入する必要があります私はforループを書くことができますが、私のデータセットがスクリプトを実行するのに長い時間がかかるでしょう。条件付き置換関数はありますか?

+0

'df.groupby( 'ID').ffill()。bfill()'は何が必要ですか? – Psidom

+0

@Psidom:はい、そうです。ありがとうございました。唯一の問題は、1GBのデータの計算を終了するのに時間がかかることです。 – duckertito

+0

df.sort_values(['ID'、 'C​​OL1']).ffill() 'を試してください。上記の方法よりも。 NaNの値をデータフレームの最後にソートし、 'ffill()'メソッドのみを使用して欠損値を埋めます。 – Psidom

答えて

1

を皮切り:プログラムでmappingを構築するには、次の2行のコードを使用することができます例として次の:

df = pd.DataFrame({'ID': list(range(10)), 'COL1': [np.random.choice([1,np.nan]) for _ in range(10)]}) 
df = pd.concat([df]*100000).reset_index(drop = True) 

df.head() 

# COL1 ID 
#0 NaN 0 
#1 1.0 1 
#2 1.0 2 
#3 NaN 3 
#4 1.0 4 

あなたが記入し、後方に欠損値を埋めるために、各グループ内のメソッドを埋める前方を使用することができます。

%timeit df.groupby('ID').ffill().bfill() 
1 loop, best of 3: 212 ms per loop 

または代替がIDCOL1によって値をソートすることで、これは、まずIDをソート各ID内のCOL1を並べ替え、すべての欠損値を各IDの末尾にプッシュしてから、ffill()、よりも速いと思われるffill()を使用することができますこの例では上記の210個の方法は:他の不要な文字列がある場合

%timeit df.sort_values(['ID', 'COL1']).ffill() 
10 loops, best of 3: 71.6 ms per loop 

、あなたは、まずNaNで文字列を置き換えるために置き換えるメソッドを呼び出すことができます。たとえば、データフレームに空の文字列がある場合は、入力します。できますdo df.replace('', np.nan).sort_values(['ID', 'COL1']).ffill()

1

Series.isnull()を使用して行を選択し、Series.map()を条件付き置換に使用することはどうですか?

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
    'ID': [123, 123, 123, 345, 345, 345], 
    'COL1': [1, 1, np.nan, 2, np.nan, np.nan], 
    'COL2':['ABC', 'CCC', 'AVV', 'FGG', 'FRG', 'FGT']}, 
    columns=['ID','COL1', 'COL2']) 

print df 
mapping = {123: 1, 345: 2} 
df.loc[df['COL1'].isnull(), 'COL1'] = df['ID'].map(mapping) 
print df 

前:

後:

ID COL1 COL2 
0 123 1.0 ABC 
1 123 1.0 CCC 
2 123 1.0 AVV 
3 345 2.0 FGG 
4 345 2.0 FRG 
5 345 2.0 FGT 

EDIT:

df_unique = df.loc[df['COL1'].notnull()].groupby('ID').nth(0) 
mapping = pd.Series(df_unique['COL1'].values, index=df_unique.index).to_dict() 
+0

私は 'mapping'を手動で定義すべきですか? – duckertito

+0

あなたの解決策は非常に面白く、自動的に 'マッピング'を作成する方法を説明すれば、柔軟性があるようです。ありがとう。 – duckertito

+0

私は 'mapping'の自動作成で編集を追加しました。私は自分のコードがPsidomのソリューションよりも遅いと思っていますが、うまくいけば、それはまだ誰かにとって有用です。 – MarredCheese