2015-10-15 16 views
7

選択した行を削除し、私はパンダのデータフレームを持っている、のような何か:その果実がエントリの奇数(ムラ)の数を(持っている場合、私は、最後のエントリ、PER果物を削除したいのpythonパンダデータフレーム:

df = pd.read_csv('fruit.csv') 

print(df) 

    fruitname quant 
0  apple  10 
1  apple  11 
2  apple  13 
3  banana  10 
4  banana  20 
5  banana  30 
6  banana  40 
7  pear  10 
8  pear 102 
9  pear 1033 
10  pear 1012 
11  pear 101 
12  pear 100 
13  pear 1044 
14 orange  10 

%2 == 1)。データフレームをループすることなくそう上記の最終的な結果は以下のようになり:

- Appleは3回 を発生するので、最後のリンゴを除去 - 最終ナシ を除去する - その結果、最後の(唯一の)オレンジ

を削除します。

fruitname quant 
0  apple  10 
1  apple  11 
2  banana  10 
3  banana  20 
4  banana  30 
5  banana  40 
6  pear  10 
7  pear 102 
8  pear 1033 
9  pear 1012 
10  pear 101 
11  pear 100 

これは可能ですか?または、DFをループする必要がありますか?私は4日間のグーグル・グーグルで、これをどうやって行うのか分かりません。

答えて

1

適用機能を使用することができます:

def remove_last_odd_row(fr): 
    nrow = fr.shape[0] 
    if nrow % 2 > 0: 
     return fr[:(nrow - 1)] 
    else: 
     return fr 

fr = fr.groupby("fruitname").apply(remove_last_odd_row).reset_index(drop=True) 
6

フルーツあたりのアイテム数を確認するには、value_countsを使用し、奇数があるかどうかに基づいてリストを作成します。 %モジュラス演算子を使用して1または0のいずれかを生成するだけでこれを実現できます。ブール値マスクを作成するにはastypeを使用してキャストします。

ブール値マスクを使用して、インデックスvalue_countsをマスクします。

今度はフルーツのリストがあり、dfをフィルタリングして最後のインデックスラベルをiloc[-1].nameという属性を使って取得し、これをリストに追加します。

dropリストでこれらのラベル:

In [393]: 
fruits = df['fruitname'].value_counts().index[(df['fruitname'].value_counts() % 2).astype(bool)] 
idx = [] 
for fruit in fruits: 
    idx.append(df[df['fruitname']==fruit].iloc[-1].name) 
df.drop(idx) 

Out[393]: 
    fruitname quant 
0  apple  10 
1  apple  11 
3  banana  10 
4  banana  20 
5  banana  30 
6  banana  40 
7  pear  10 
8  pear 102 
9  pear 1033 
10  pear 1012 
11  pear 101 
12  pear 100 

上記の内訳:

In [394]: 
df['fruitname'].value_counts() 

Out[394]: 
pear  7 
banana 4 
apple  3 
orange 1 
Name: fruitname, dtype: int64 

In [398]: 
df['fruitname'].value_counts() % 2 

Out[398]: 
pear  1 
banana 0 
apple  1 
orange 1 
Name: fruitname, dtype: int64 

In [399]: 
fruits = df['fruitname'].value_counts().index[(df['fruitname'].value_counts() % 2).astype(bool)] 
fruits 

Out[399]: 
Index(['pear', 'apple', 'orange'], dtype='object') 

In [401]:  
for fruit in fruits: 
    print(df[df['fruitname']==fruit].iloc[-1].name) 

13 
2 
14 

を実際にあなたは次のことがうまくいくようにlast_valid_indexの代わりiloc[-1].nameを使用することができます。

fruits = df['fruitname'].value_counts().index[(df['fruitname'].value_counts() % 2).astype(bool)] 
idx = [] 
for fruit in fruits: 
    idx.append(df[df['fruitname']==fruit].last_valid_index()) 
df.drop(idx) 
0

パンダはあまりよく知らないけどreは答えです。

for fruit in pd.unique(df.fruitname): 
    df1=df[df.fruitname==fruit] 
    if len(df1)%2 == 1: 
     df=df.drop(df1.last_valid_index()) 
5

groupbyを使用していますEdChumのための別のアプローチ、:これは、それがアップ放送するので、一種の変換のタイプのように振る舞いtransform(とcumcountを、使用して動作

>>> grouped = df.groupby("fruitname")["fruitname"] 
>>> lengths = grouped.transform(len) 
>>> df.loc[~((lengths % 2 == 1) & (grouped.cumcount() == lengths-1))] 
    fruitname quant 
0  apple  10 
1  apple  11 
3  banana  10 
4  banana  20 
5  banana  30 
6  banana  40 
7  pear  10 
8  pear 102 
9  pear 1033 
10  pear 1012 
11  pear 101 
12  pear 100 

元のインデックス)を使用して、私たちが扱えるフレーム長シリーズを提供します:

>>> lengths 
0  3 
1  3 
2  3 
3  4 
4  4 
5  4 
6  4 
7  7 
8  7 
9  7 
10 7 
11 7 
12 7 
13 7 
14 1 
Name: fruitname, dtype: object 
>>> grouped.cumcount() 
0  0 
1  1 
2  2 
3  0 
4  1 
5  2 
6  3 
7  0 
8  1 
9  2 
10 3 
11 4 
12 5 
13 6 
14 0 
dtype: int64 
+0

あなたは非常に狡猾です;)+1 – EdChum

関連する問題