[英]python pandas dataframe : removing selected rows
我有一個pandas數據幀,如:
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
我想刪除最后一個條目PER FRUIT,如果該水果有一個奇數(不均勻)條目數(%2 == 1)。 沒有循環數據幀。 所以上面的最終結果是:
- 刪除最后一個蘋果,因為蘋果發生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天,只是無法弄清楚如何做到這一點。
使用value_counts
確定每個水果的項目數,並根據是否存在奇數來構建它們的列表。 我們可以通過使用%
模數運算符生成1
或0
來實現這一點,使用astype
來構建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)
EdChum的另一種方法,它使用groupby
:
>>> 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
這通過使用transform
(和cumcount
,其行為類似於一種變換,因為它廣播到原始索引)來為我們提供一個我們可以使用的幀長系列:
>>> 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
你可以使用apply函數:
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)
我對熊貓不是很熟悉,但這是一個答案。
for fruit in pd.unique(df.fruitname):
df1=df[df.fruitname==fruit]
if len(df1)%2 == 1:
df=df.drop(df1.last_valid_index())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.