Инкрементальная группа через pandas - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь выполнить инкрементную группировку и ранжировать в pandas.

Пример DF:

df = pd.DataFrame(np.random.randint(0,20,size=(7,3)),columns=["a","b","c"])
df["d1"]=["Apple","Mango","Apple","Mango","Mango","Mango","Apple"]
df["d2"]=["Orange","lemon","lemon","Orange","lemon","Orange","lemon"]
df["date"] = ["2002-01-01","2002-01-01","2002-01-01","2002-01-01","2002-02-01","2002-02-01","2002-02-01"]
df["date"] = pd.to_datetime(df["date"])
df


    a   b   c     d1      d2     date
0   7   1   4   Apple   Orange  2002-01-01
1   3   7   6   Mango   lemon   2002-01-01
2   9   6   9   Apple   lemon   2002-01-01
3   0   5   8   Mango   Orange  2002-01-01
4   4   6   7   Mango   lemon   2002-02-01
5   4   3   8   Mango   Orange  2002-02-01
6   0   2   8   Apple   lemon   2002-02-01

Попытка увеличить Группировку на d1 и ранжировать каждую строку столбца d1 на основе другого столбца c.

Для lo c [0,"d1"] значение Apple будет рангом 0, поскольку есть только строка и сравнение не выполняется.

Для lo c [1,"d1"] значение Mango будет 1, потому что с учетом первых двух строк соответствующее значение Apple в столбце C, т.е. значение [0,"c"] равно 4 (Apple), а значение [1,"C"] равно 6 (для Man go), поэтому Man go имеет более высокий ранг в этом нарезанном DF

Для lo c [2,"d1"] значение Apple будет 1, потому что с учетом первых трех строк соответствующее значение Apple в столбце C, то есть значение [0,"c"] равно 4 (Apple), а значение [1,"C"] равно 6 (для Man go) значение [2,"c"] равно 9 (Apple), поэтому среднее из 2 значений для Apple равно (4+9)/2 =6.5, а значение Mango равно 6, поэтому Apple будет ранг 1.

Постепенно следуя той же схеме и обновляя значение столбца d1 в последнем индексе инкрементально нарезанного DF.

Ожидаемые значения для столбца d1:

0
1
1
1 => since for Apple (4+9)/2 and for Mango (6+8)/2
1 => since for Apple (4+9)/2 and for Mango (6+8+7)/3
1 => since for Apple (4+9)/2 and for Mango (6+8+7+8)/4
0 => since for Apple (4+9+8)/2 and for Mango (6+8+7+8)/4

Я могу сделать это в for l oop, итеративно нарезав df[:i], но для больших DF это займет вечность, любые предложения по подходу, основанному на более pandas, будут отлично.

Применяя первое решение к следующему случайному DF:

    a   b   c     d1       d2    date
0   7   1   19  Apple   Orange  2002-01-01
1   3   7   17  Mango   lemon   2002-01-01
2   9   6   4   Apple   lemon   2002-01-01
3   0   5   15  Apple   Orange  2002-01-01
4   4   6   8   Mango   lemon   2002-02-01
5   4   3   1   Mango   Orange  2002-02-01
6   2   2   14  Apple   lemon   2002-02-01
7   5   15  10  Mango   Orange  2002-01-01
8   1   2   10  Apple   lemon   2002-02-01
9   2   1   12  Apple   Orange  2002-02-01

Я получаю следующие значения для d1:

0
0
0
1
0
0
1
0
1
0
      

последнее значение неправильно, потому что в этот момент значение Apple равно 12.33 (19 + 4 + 15 + 14 + 10 + 12) / 6, а Mango равно 9 (17 + 8 + 1 + 10) / 4, поэтому последнее значение d1 должно быть 1.

1 Ответ

1 голос
/ 10 июля 2020

Обновлено для второго фрейма данных:

   a   b   c     d1       d2    date
0   7   1   19  Apple   Orange  2002-01-01
1   3   7   17  Mango   lemon   2002-01-01
2   9   6   4   Apple   lemon   2002-01-01
3   0   5   15  Apple   Orange  2002-01-01
4   4   6   8   Mango   lemon   2002-02-01
5   4   3   1   Mango   Orange  2002-02-01
6   2   2   14  Apple   lemon   2002-02-01
7   5   15  10  Mango   Orange  2002-01-01
8   1   2   10  Apple   lemon   2002-02-01
9   2   1   12  Apple   Orange  2002-02-01

s = df.groupby('d1')['c'].expanding().mean().sort_index(level=1)

Вывод:

Apple  0    19.000000
Mango  1    17.000000
Apple  2    11.500000
       3    12.666667
Mango  4    12.500000
       5     8.666667
Apple  6    13.000000
Mango  7     9.000000
Apple  8    12.400000
       9    12.333333

Что нам нужно сделать на этом этапе? Правильны ли эти средние значения?

И если я использую s.diff().ge(0) для сравнения средних, вы получите:

Apple  0    0
Mango  1    0
Apple  2    0
       3    1
Mango  4    0
       5    0
Apple  6    1
Mango  7    0
Apple  8    1
       9    0

IIU C,

Посмотрите на это:

df.groupby('d1')['c'].expanding().mean().sort_index(level=1)

Вывод:

Apple  0    4.00  #4
Mango  1    6.00  #6
Apple  2    6.50  #9+4 / 2
Mango  3    7.00  #6 + 8 / 2
       4    7.00  #6 + 8 + 7 / 3
       5    7.25  #6 + 8 + 7 + 8 / 4
Apple  6    7.00  #4 + 9 + 8 / 3
Name: c, dtype: float64

Теперь сравним с предыдущей строкой:

df.groupby('d1')['c'].expanding().mean().sort_index(level=1).diff().ge(0).astype(int)

Вывод:

d1      
Apple  0    0
Mango  1    1
Apple  2    1
Mango  3    1
       4    1
       5    1
Apple  6    0
Name: c, dtype: int32

Или, может быть, вам нужно сравнить Man go с последним значением яблока ....

df.groupby('d1')['c'].expanding().mean().sort_index(level=1).unstack(0).ffill()

Вывод:

d1  Apple  Mango
0     4.0    NaN
1     4.0   6.00
2     6.5   6.00
3     6.5   7.00
4     6.5   7.00
5     6.5   7.25
6     7.0   7.25

Однако я не могу сопоставить ожидаемый результат:

df.groupby('d1')['c'].expanding().mean().sort_index(level=1).unstack(0).ffill().eval('rank= Mango >= Apple')

Вывод:

d1  Apple  Mango   rank
0     4.0    NaN  False
1     4.0   6.00   True
2     6.5   6.00  False
3     6.5   7.00   True
4     6.5   7.00   True
5     6.5   7.25   True
6     7.0   7.25   True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...