У меня есть огромный набор данных, где мне нужно хрустеть много цифр и искать 1. для реального решения и 2. для быстрого.Pandas: вычитание двух серий с конкретным соответствием индексу
Я попытался упростить и перенести свою проблему на пример реального мира как можно лучше, надеюсь, это ясно. Я уверен (по крайней мере, надеюсь), это как-то обычная проблема в Пандах, а не очень особенная.
Итак, у меня есть два сотрудника в компании под названием foo
и bar
. Иногда они работают в один и тот же день и повторяют одну и ту же задачу снова и снова. Я измеряю время, необходимое для выполнения задачи (иногда только один раз в день, иногда несколько раз).
Что я ищу сейчас, это разница между кратчайшими моментами, если оба они работали в тот же день.
Я стараюсь использовать метод непросеянной муки, так что работа с таблицей (и не повторение) в максимально возможной степени.
Моя текущая стратегия: сгруппировать данные по day
и name
, держать только самый короткий time
за day
и name
, если размер группы 2 (что означает, что я есть данные для обоих работников в тот же день) вычитают оба раза.
Конечная цель: имеющее Series
отличия в раскраске кратчайшие.
Однако мне не удалось выполнить группировку и фильтрацию, поэтому теперь я пытаюсь создать две серии для обоих рабочих, а затем вычислить разницу во времени.
Ниже приведен пример набора данных:
from StringIO import StringIO
import pandas as pd
raw_data="""day name time
1 foo 10
1 foo 9
1 bar 4
2 foo 12
2 foo 13
3 bar 3
3 bar 5
5 foo 8
5 bar 5
5 foo 9
5 bar 1
"""
df = pd.read_csv(StringIO(raw_data), sep=' ')
grouped_by_day_and_name = df.groupby(['day', 'name'])
Это как таблица выглядит как после группировки и сохраняя только кратчайшее время:
print grouped_by_day_and_name.agg({'time': min})
time
day name
1 bar 4
foo 9
2 foo 12
3 bar 3
5 bar 1
foo 8
Теперь я заинтересован только в день 1 и 5, так как это единственные дни, у меня есть данные как для bar
, так и для foo
. Поэтому я бы закончил, если бы я каким-то образом мог фильтровать данные и вычитать оба раза в каждой группе, поэтому результат будет [-5, -7]
(со дня 1: 4-9, 5 день 1-8).
Поскольку я не был в состоянии фильтровать и вычитать, я пытаюсь создать серию для обоих имен и вычитать каждый из них, однако показатели не совпадают:
foo_best_times = df[df.name == 'foo'].groupby(['day', 'name']).agg({'time': min})
bar_best_times = df[df.name == 'bar'].groupby(['day', 'name']).agg({'time': min})
После попытки вычесть каждый один:
print foo_best_times - bar_best_times
time
day name
1 bar NaN
foo NaN
2 foo NaN
3 bar NaN
5 bar NaN
foo NaN
Что я задался для что-то вроде этого:
day time
1 -5
2 NaN
3 NaN
5 -7
Как бы я вычесть оба ряда, сопоставив только индекс day
как индекс?
Это даже правильный подход, чтобы сделать это быстро?
Может ли только когда-либо быть два сотрудника вашей аналогии? –
Возможно, вы можете сбросить индекс, например, 'print foo_best_times.reset_index (level = 1) ['time'] - bar_best_times.reset_index (level = 1) ['time']' – jezrael
В принципе, могут быть и несколько сотрудников, однако я стараюсь выяснить этот случай сам. Это было бы уже огромно, если бы я решил проблему с двумя рабочими ;-) – tamasgal