我有一个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
Run Code Online (Sandbox Code Playgroud)
我想删除最后一个条目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
Run Code Online (Sandbox Code Playgroud)
这可能吗?或者我必须循环DF?我一直在谷歌搜索4天,只是无法弄清楚如何做到这一点.
确定每个水果使用的项目数量,value_counts并根据是否有奇数来建立它们的列表.我们可以通过使用%模运算符生成a 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
Run Code Online (Sandbox Code Playgroud)
突破以上:
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
Run Code Online (Sandbox Code Playgroud)
实际上你可以使用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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这通过使用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
Run Code Online (Sandbox Code Playgroud)
您可以使用 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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
773 次 |
| 最近记录: |