Вариант 0
Использование value_counts
и isin
df[~df.lid.isin(df.lid.value_counts().loc[lambda x: x > 2].index)]
entity pnb head# state lid
3 ABB002 A02 4 DOWN B
4 ABB002 A02 4 DOWN B
5 ABB002 A02 2 DOWN C
6 ABB002 A02 4 DOWN D
Вариант 1
Лучше реализовать с np.in1d
и pd.factorize
lids = df.lid.values
f, u = pd.factorize(df.lid.values)
df[np.in1d(lids, u[np.bincount(f) <= 2])]
entity pnb head# state lid
3 ABB002 A02 4 DOWN B
4 ABB002 A02 4 DOWN B
5 ABB002 A02 2 DOWN C
6 ABB002 A02 4 DOWN D
Вариант 2
Использование np.bincount
и pd.factorize
f, u = pd.factorize(df.lid)
df[np.bincount(f)[f] <= 2]
entity pnb head# state lid
3 ABB002 A02 4 DOWN B
4 ABB002 A02 4 DOWN B
5 ABB002 A02 2 DOWN C
6 ABB002 A02 4 DOWN D
Для забавной демонстрации, чтобы подчеркнуть то, о чем мы с @cᴏʟᴅsᴘᴇᴇᴅ говорили в комментариях.
Люблю bincount один. Где-то тоже должен быть np.unique. – cᴏʟᴅsᴘᴇᴇᴅ
Да, есть. Однако я не использую np.unique, потому что @Jeff сообщил мне, что np.unique сортируется, когда вы берете счетчики, индексируете или инверсируете. pd.factorize не работает и равен O (n). С тех пор я подтвердил эту информацию. - piRSquared
Тест времени
def bincount_factorize(df):
f, u = pd.factorize(df.lid.values)
return df[np.bincount(f)[f] <= 2]
def bincount_unique(df):
u, f = np.unique(df.lid.values, return_inverse=True)
return df[np.bincount(f)[f] <= 2]
def in1d_factorize(df):
lids = df.lid.values
f, u = pd.factorize(df.lid.values)
return df[np.in1d(lids, u[np.bincount(f) <= 2])]
def transform(df):
return df[df.groupby('lid')['lid'].transform('size') <= 2]
res = pd.DataFrame(
index=[10, 30, 100, 300, 1000, 3000, 10000,
30000, 100000, 300000, 1000000],
columns=['bincount_factorize', 'bincount_unique',
'in1d_factorize', 'transform'],
dtype=float
)
for i in res.index:
d = pd.concat([df] * i, ignore_index=True)
for j in res.columns:
stmt = f'{j}(d)'
setp = f'from __main__ import d, {j}'
res.at[i, j] = timeit(stmt, setp, number=100)
res.div(res.min(1), 0)
bincount_factorize bincount_unique in1d_factorize transform
10 1.421827 1.000000 1.119577 3.751167
30 1.008412 1.037297 1.000000 3.072631
100 1.000000 1.531300 1.028267 3.304560
300 1.000000 2.666583 1.182812 3.637235
1000 1.065213 5.563098 1.000000 2.556469
3000 1.024658 10.480027 1.000000 2.238765
10000 1.073403 14.716801 1.000000 1.574780
30000 1.000000 16.387130 1.053180 1.494161
100000 1.000000 18.533078 1.003031 1.369867
300000 1.078129 20.183122 1.000000 1.530698
1000000 1.166800 24.571463 1.000000 1.670423
res.plot(loglog=True)
![введите здесь описание изображения](https://i.stack.imgur.com/o1Dny.png)
16.01.2018
np.unique
. 16.01.2018np.unique
, потому что @Jeff сообщил мне, чтоnp.unique
сортируется, когда вы берете подсчеты, индексируете или инверсируете.pd.factorize
нет и являетсяO(n)
. С тех пор я подтвердил эту информацию. 16.01.2018