Цикл, который считает уникальные значения в панде df - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь создать loop или более эффективный процесс, который может count количество текущих значений в pandas df. В данный момент я выбираю значение, для которого я хочу выполнить функцию.

Итак, для df ниже я пытаюсь определить два counts.

1) ['u'] возвращает количество тех же оставшихся значений, оставшихся в ['Code', 'Area']. Итак, сколько оставшихся раз встречаются одинаковые значения.

2) ['On'] возвращает количество значений, которые в настоящее время встречаются в ['Area']. Это достигается путем анализа df, чтобы увидеть, не произойдут ли эти значения снова. Так что, по сути, он смотрит в будущее, чтобы увидеть, появятся ли эти значения снова.

import pandas as pd

d = ({
    'Code' : ['A','A','A','A','B','A','B','A','A','A'],            
    'Area' : ['Home','Work','Shops','Park','Cafe','Home','Cafe','Work','Home','Park'],  
     })

df = pd.DataFrame(data=d)

#Select value
df1 = df[df.Code == 'A'].copy()

df1['u'] = df1[::-1].groupby('Area').Area.cumcount()

ids = [1]
seen = set([df1.iloc[0].Area])
dec = False
for val, u in zip(df1.Area[1:], df1.u[1:]):
    ids.append(ids[-1] + (val not in seen) - dec)
    seen.add(val)
    dec = u == 0
df1['On'] = ids

df1 = df1.reindex(df.index).fillna(df1)

Проблема в том, что я хочу запустить этот скрипт для всех значений в Code. Вместо того, чтобы выбирать по одному. Например, если я хочу сделать то же самое на Code['B'], мне придется изменить: df2 = df1[df1.Code == 'B'].copy() и снова запустить скрипт.

Если у меня есть многочисленные значения в Code, это становится очень неэффективным. Мне нужно loop, где он находит все unique значения в 'Code' В идеале скрипт должен выглядеть следующим образом:

df1 = df[df.Code == 'All unique values'].copy()

Предполагаемый вывод:

  Code   Area    u   On
0    A   Home  2.0  1.0
1    A   Work  1.0  2.0
2    A  Shops  0.0  3.0
3    A   Park  1.0  3.0
4    B   Cafe  1.0  1.0
5    A   Home  1.0  3.0
6    B   Cafe  0.0  1.0
7    A   Work  0.0  3.0
8    A   Home  0.0  2.0
9    A   Park  0.0  1.0

Ответы [ 3 ]

0 голосов
/ 10 сентября 2018

Этот процесс применяет ваш рабочий процесс к каждому коду в таблице:

def yourFunc(df1):
    df1['u'] = df1[::-1].groupby('Area').Area.cumcount()

    ids = [1]
    seen = set([df1.iloc[0].Area])
    dec = False
    for val, u in zip(df1.Area[1:], df1.u[1:]):
        ids.append(ids[-1] + (val not in seen) - dec)
        seen.add(val)
        dec = u == 0
    df1['On'] = ids

    df1 = df1.reindex(df.index).fillna(df)
    return(df1)

test = df.groupby('Code').apply(yourFunc)

тест:

        Area    Code u  On
Code                    
A   
    0   Home    A   2.0 1.0
    1   Home    A   1.0 1.0
    2   Shops   B   NaN NaN
    3   Park    A   1.0 2.0
    4   Cafe    B   NaN NaN
    5   Shops   B   NaN NaN
    6   Home    A   0.0 2.0
    7   Cafe    B   NaN NaN
    8   Work    A   0.0 2.0
    9   Park    A   0.0 1.0
B   
    0   Home    A   NaN NaN
    1   Home    A   NaN NaN
    2   Shops   B   1.0 1.0
    3   Park    A   NaN NaN
    4   Cafe    B   1.0 2.0
    5   Shops   B   0.0 2.0
    6   Home    A   NaN NaN
    7   Cafe    B   0.0 1.0
    8   Work    A   NaN NaN
    9   Park    A   NaN NaN
0 голосов
/ 10 сентября 2018

Я считаю вашу логику «Вкл.» Очень запутанной. Тем не менее, я думаю, что я могу воспроизвести это:

df["u"] = df.groupby(["Code", "Area"]).cumcount(ascending=False)
df["nunique"] = pd.get_dummies(df.Area).groupby(df.Code).cummax().sum(axis=1)
df["On"] = (df["nunique"] - 
           (df["u"] == 0).groupby(df.Code).cumsum().groupby(df.Code).shift().fillna(0)

, что дает мне

In [212]: df
Out[212]: 
  Code   Area  u  nunique   On
0    A   Home  2        1  1.0
1    A   Work  1        2  2.0
2    A  Shops  0        3  3.0
3    A   Park  1        4  3.0
4    B   Cafe  1        1  1.0
5    A   Home  1        4  3.0
6    B   Cafe  0        1  1.0
7    A   Work  0        4  3.0
8    A   Home  0        4  2.0
9    A   Park  0        4  1.0

В этом u - это количество совпадающих пар (Код, Площадь) после этой строки. nunique - это число уникальных значений Area, видимых до сих пор в этом Кодексе. На это число уникальных Областей, замеченных до сих пор, за исключением того, что, как только мы «исчерпали» Зону - когда она больше не используется - мы начинаем вычитать ее из nuniq.

0 голосов
/ 09 сентября 2018

Используя GroupBy с size и cumcount, вы можете создать свою серию u.

Ваша логика для On не ясна: это требует уточнения.

g = df.groupby(['Code', 'Area'])
df['u'] = g['Code'].transform('size') - (g.cumcount() + 1)

print(df)

  Code   Area  u
0    A   Home  2
1    A   Home  1
2    B  Shops  1
3    A   Park  1
4    B   Cafe  1
5    B  Shops  0
6    A   Home  0
7    B   Cafe  0
8    A   Work  0
9    A   Park  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...