Jupyter Pandas - отбрасывание предметов со средним значением выше порога

У меня есть фрейм данных с товарами и их ценами, примерно так: ╔══════╦═════╦═══════╗ ║ Item ║ Day ║ Price ║ ╠══════╬═════╬═══════╣ ║ A ║ 1 ║ 10 ║ ║ B ║ 1 ║ 20 ║ ║ C ║ 1 ║ 30 ║ ║ D ║ 1 ║ 40 ║ ║ A ║ 2 ║ 100 ║ ║ B ║ 2 ║ 20 ║ ║ C ║ 2 ║ 30 ║ ║ D ║ 2 ║ 40 ║ ║ A ║ 3 ║ 500 ║ ║ B ║ 3 ║ 25 ║ ║ C ║ 3 ║ 35 ║ ║ D ║ 3 ║ 1000 ║ ╚══════╩═════╩═══════╝

Я хочу исключить все строки из этого df, где средняя цена элемента превышает 200. Итак, отфильтрованный df должен выглядеть так: ╔══════╦═════╦═══════╗ ║ Item ║ Day ║ Price ║ ╠══════╬═════╬═══════╣ ║ B ║ 1 ║ 20 ║ ║ C ║ 1 ║ 30 ║ ║ B ║ 2 ║ 20 ║ ║ C ║ 2 ║ 30 ║ ║ B ║ 3 ║ 25 ║ ║ C ║ 3 ║ 35 ║ ╚══════╩═════╩═══════╝

Я новичок в python и pandas, но на первом этапе я подумал о чем-то вроде этого, чтобы получить новый df для средних цен: avg_prices_df = df.groupby ('ItemID'). Price.mean (). Reset_index, а затем не уверен, как исходить оттуда. Не уверен, что даже этот первый шаг верен.

Чтобы еще больше усложнить ситуацию, я использую vaex для чтения данных в форме ndf5, так как у меня более 400 миллионов строк.

Большое спасибо за любой совет.

РЕДАКТИРОВАТЬ: Итак, у меня работает следующий код, хотя я уверен, что он не оптимизирован ..

`

создать фрейм данных с идентификаторами предметов и их средними ценами

df_item_avg_price = df.groupby (df.ItemID, agg = [vaex.agg.count ('ItemID'), vaex.agg.mean ('Price')])

отфильтровать этот новый фрейм данных по порогу средней цены

df_item_avg_price = (df_item_avg_price [df_item_avg_price ["P_r_i_c_e_mean"] ‹= 50000000])

создать список идентификаторов товаров, средняя цена которых ниже порогового значения

items_in_price_range = df_item_avg_price ['ItemID']. tolist ()

отфильтровать исходный фрейм данных, чтобы включить строки только с элементами в ценовом диапазоне

filter_df = df [df.ItemID.isin (items_in_price_range)] `Есть способ сделать это лучше?


person dalayr    schedule 08.12.2019    source источник
comment
Пожалуйста, включите свои данные в формате, который будет удобочитаемым и удобным для других.   -  person AMC    schedule 08.12.2019
comment
Да, я пробовал. Как мне сделать так, чтобы таблицы отображались здесь правильно? Ответ @jezrael был таким аккуратным и аккуратным. Я попытался использовать преобразователь таблицы в ascii, а затем вставить ascii в кавычки кода.   -  person dalayr    schedule 08.12.2019
comment
Мне нравится библиотека таблиц для удобочитаемости, CSV великолепен с точки зрения простоты использования, и его можно сделать вполне читабельным.   -  person AMC    schedule 08.12.2019


Ответы (2)



Позвольте мне показать вам, как я бы это сделал (главный автор vaex), хотя Jupyter Pandas - удаление элементов, среднее значение которых превышает пороговое значение, почти готово.

Давайте сначала создадим фрейм данных:

data = [["A", 1,  10],
["A", 1,  10],
["B", 1,  20],
["C", 1,  30],
["D", 1,  40],
["A", 2, 100],
["B", 2,  20],
["C", 2,  30],
["D", 2,  40],
["A", 3, 500],
["B", 3,  25],
["C", 3,  35],
["D", 3, 1000]]

import vaex
df = vaex.from_arrays(Item=[k[0] for k in data], Day=[k[1] for k in data], Price=[k[2] for k in data])
print(df)
#    Item    Day    Price
0    A       1      10
1    A       1      10
2    B       1      20
3    C       1      30
4    D       1      40
...  ...     ...    ...
8    D       2      40
9    A       3      500
10   B       3      25
11   C       3      35
12   D       3      1000

И сгенерируйте фрейм данных со средними ценами:

df_avg_price = df.groupby(df.Item, agg={"Price": 'mean'})
print(df_avg_price)
#  Item       Price
0  A       155
1  B        21.6667
2  C        31.6667
3  D       360

Последний выпуск vaex не любит повторное присоединение из-за повторяющегося имени (Item) в обоих фреймах данных, несмотря на присоединение столбца (это исправлено в master (https://github.com/vaexio/vaex), но мы можем обойти это, используя префикс для правильного фрейма данных.

df2 = df.join(df_avg_price, on='Item', rprefix='avg')
df2 = df2[df2.avgPrice < 200]  # notice the prefix

Если вы хотите избавиться от других столбцов:

df2 = df2[['Item', 'Day', 'Price']]  # only get the rows we want
print(df2)
#  Item      Day    Price
0  A           1       10
1  A           1       10
2  B           1       20
3  C           1       30
4  A           2      100
5  B           2       20
6  C           2       30
7  A           3      500
8  B           3       25
9  C           3       35
person Maarten Breddels    schedule 11.12.2019