Фильтрация Pandas на основе длины однотипных переменных в столбце

В моем реальном случае у меня есть набор временных рядов, связанных с разными идентификаторами, хранящимися в одном DataFrame
Некоторые состоят из 400 семплов, некоторые из 1000 семплов, некоторые из 2000. Они хранятся в одном df и:

Я хотел бы отбросить все идентификаторы, состоящие из временных рядов короче заданной длины.

Я написал следующий код, но считаю его очень некрасивым и неэффективным.

import pandas as pd
import numpy as np

dict={"samples":[1,2,3,4,5,6,7,8,9],"id":["a","b","c","b","b","b","c","c","c"]}
df=pd.DataFrame(dict)

df_id=pd.DataFrame()

for i in set(df.id):
  df_filtered=df[df.id==i]
  len_id=len(df_filtered.samples)

  if len_id>3: #3 is just a random choice for this example
    df_id=df_id.append(df_filtered)
print(df_id)

Выход:

   samples id
2        3  c
6        7  c
7        8  c
8        9  c
1        2  b
3        4  b
4        5  b
5        6  b

Как улучшить его более питоническим способом? Спасибо

2 ответа
2

Хороший ответ Юхо. Другой вариант — это groupby-filter:

df.groupby('id').filter(lambda group: len(group) > 3)

#    samples id
# 1        2  b
# 2        3  c
# 3        4  b
# 4        5  b
# 5        6  b
# 6        7  c
# 7        8  c
# 8        9  c

Чтобы точно соответствовать вашему порядку вывода, добавьте убывающий id Сортировать: .sort_values('id', ascending=False)

  • Это тоже здорово.

    — Юхо

Есть много решений. Например, вы можете использовать групповое преобразование и отбрасывать «маленькие» образцы. Подходящее решение будет зависеть от ваших требований, т. Е. Проведете ли вы предварительную обработку один раз, а затем сбросите разные образцы?

Во всяком случае, учтите:

import pandas as pd

df = pd.DataFrame({"samples": [1,2,3,4,5,6,7,8,9], "id": ["a","b","c","b","b","b","c","c","c"]})

df["counts"] = df.groupby("id")["samples"].transform("count")
df[df["counts"] > 3]

# Or if you want:
df[df["counts"] > 3].drop(columns="counts")

Кстати, избегайте использования dict как имя переменной.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *