ChatGPT解决这个技术问题 Extra ChatGPT

熊猫“计数(不同)”等效

我使用 Pandas 作为数据库替代品,因为我有多个数据库(OracleSQL Server 等),并且我无法将命令序列转换为 SQL 等效项。

我在 DataFrame 中加载了一个表,其中包含一些列:

YEARMONTH, CLIENTCODE, SIZE, etc., etc.

在 SQL 中,计算每年不同客户的数量是:

SELECT count(distinct CLIENTCODE) FROM table GROUP BY YEARMONTH;

结果将是

201301    5000
201302    13245

我怎样才能在熊猫中做到这一点?

我已经完成了 table.groupby(['YEARMONTH'])['CLIENTCODE'].unique() 并带有由 YEARMONTH 索引的两个系列和所有唯一值。如何计算每个系列的值的数量?
对于某些人来说,value_counts 可能是您正在寻找的答案:pandas.pydata.org/pandas-docs/stable/generated/…

L
LondonRob

我相信这就是你想要的:

table.groupby('YEARMONTH').CLIENTCODE.nunique()

例子:

In [2]: table
Out[2]: 
   CLIENTCODE  YEARMONTH
0           1     201301
1           1     201301
2           2     201301
3           1     201302
4           2     201302
5           2     201302
6           3     201302

In [3]: table.groupby('YEARMONTH').CLIENTCODE.nunique()
Out[3]: 
YEARMONTH
201301       2
201302       3

如果我有多个列,我希望它们是唯一的,比如在 .drop_duplicates(subset=['col1','col2']) 中,该怎么办?
如何访问此唯一计数。因为没有列名
非常感谢,我在重采样的输出中使用了这种风格。 df_watch_record.resample('M').user.nunique() 计算每月观看电影的唯一用户数。
并使用 table.groupby('YEARMONTH').CLIENTCODE.nunique().sort_values(ascending=False) 对它们进行排序
是否可以将其应用于多个列?现在在示例中,仅选择了一列。
P
Peter Mortensen

这是另一种方法,它更简单。假设您的数据框名称为 daat,列名称为 YEARMONTH

daat.YEARMONTH.value_counts()

我喜欢这个答案。如果我的列名有“。”,我该如何使用此方法在其中(例如'ck.Class')?谢谢
daat['ck.Class'].value_counts()
这没有解决所提出的问题。
这计算了每组内的观察次数,而不是每组具有的某个列的唯一值。
这是错误的答案;它没有反映问题中的 DISTINCT 要求!此外,它不包括 NaN 的计数!
j
jezrael

有趣的是,len(unique()) 通常比 nunique() 快几倍 (3x-15x)。


你是这个意思? .CLIENTCODE.apply(lambda x: len(x.unique())),来自 here
@user32185 您必须将其放入带有 lambda 的 apply 调用中。例如,df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0])
语法不完全清楚,我用 len(df['column'].unique()) 不需要 lambda 函数
我从 Chen's 评论中得到了 TypeError: object of type 'method' has no len()3novak's 为我工作。
G
Gangaraju

我也在使用 nunique,但如果您必须使用 'min', 'max', 'count' or 'mean' 等聚合函数,这将非常有帮助。

df.groupby('YEARMONTH')['CLIENTCODE'].transform('nunique') #count(distinct)
df.groupby('YEARMONTH')['CLIENTCODE'].transform('min')     #min
df.groupby('YEARMONTH')['CLIENTCODE'].transform('max')     #max
df.groupby('YEARMONTH')['CLIENTCODE'].transform('mean')    #average
df.groupby('YEARMONTH')['CLIENTCODE'].transform('count')   #count

V
Vivek Payasi

列的不同以及其他列上的聚合

要获取任何列的不同数量的值(在您的情况下为 CLIENTCODE),我们可以使用 nunique。我们可以在 agg 函数中将输入作为字典传递,以及其他列上的聚合:

grp_df = df.groupby('YEARMONTH').agg({'CLIENTCODE': ['nunique'],
                                      'other_col_1': ['sum', 'count']})

# to flatten the multi-level columns
grp_df.columns = ["_".join(col).strip() for col in grp_df.columns.values]

# if you wish to reset the index
grp_df.reset_index(inplace=True)

我认为这个答案是最好的,因为它更接近您在 SQL 中使用不同计数的方式。如果您使用 Pandas agg 的最新语法,您甚至可以跳过展平步骤。 grp_df = df.groupby('YEARMONTH').agg(CLIENTCODE_UNIQ_CNT = ('CLIENTCODE', 'nunique'), other_col_1_sum = ('other_col_1', 'sum'), other_col_1_cnt = ('other_col_1', 'count'))
哦,太好了,我不知道这种新语法。感谢您的评论:)
P
Peter Mortensen

使用 crosstab,这将返回比 groupby nunique 更多的信息:

pd.crosstab(df.YEARMONTH,df.CLIENTCODE)
Out[196]:
CLIENTCODE  1  2  3
YEARMONTH
201301      2  1  0
201302      1  2  1

稍作修改后,结果如下:

pd.crosstab(df.YEARMONTH,df.CLIENTCODE).ne(0).sum(1)
Out[197]:
YEARMONTH
201301    2
201302    3
dtype: int64

如何将其导出为两列 YEARMONTHcount。我也可以按降序设置计数吗?
P
Peter Mortensen

这是一种在多列上计数不同的方法。让我们有一些数据:

data = {'CLIENT_CODE':[1,1,2,1,2,2,3],
        'YEAR_MONTH':[201301,201301,201301,201302,201302,201302,201302],
        'PRODUCT_CODE': [100,150,220,400,50,80,100]
       }
table = pd.DataFrame(data)
table

CLIENT_CODE YEAR_MONTH  PRODUCT_CODE
0   1       201301      100
1   1       201301      150
2   2       201301      220
3   1       201302      400
4   2       201302      50
5   2       201302      80
6   3       201302      100

现在,列出感兴趣的列并以稍微修改的语法使用 groupby:

columns = ['YEAR_MONTH', 'PRODUCT_CODE']
table[columns].groupby(table['CLIENT_CODE']).nunique()

我们获得:

YEAR_MONTH  PRODUCT_CODE CLIENT_CODE
1           2            3
2           2            3
3           1            1

P
Peter Mortensen

使用新的 Pandas 版本,很容易得到一个数据框:

unique_count = pd.groupby(['YEARMONTH'], as_index=False).agg(uniq_CLIENTCODE=('CLIENTCODE', pd.Series.count))

版本号是多少?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似内容 - 答案应该看起来好像是今天写的)。
P
Peter Mortensen

创建一个数据透视表并使用 nunique series 函数:

ID = [ 123, 123, 123, 456, 456, 456, 456, 789, 789]
domain = ['vk.com', 'vk.com', 'twitter.com', 'vk.com', 'facebook.com',
          'vk.com', 'google.com', 'twitter.com', 'vk.com']
df = pd.DataFrame({'id':ID, 'domain':domain})
fp = pd.pivot_table(data=df, index='domain', aggfunc=pd.Series.nunique)
print(fp)

输出:

               id
domain
facebook.com   1
google.com     1
twitter.com    2
vk.com         3

但样本数据与问题不匹配(YEARMONTH、CLIENTCODE 和 SIZE)。 The accepted answer 和大多数其他答案一样。这个答案(在其当前状态下)将更适合问题 Count unique values with Pandas per groups
数据透视表使用函数进行聚合。
P
Peter Mortensen

现在您还可以在 Python 中使用 dplyr 语法来执行此操作:

>>> from datar.all import f, tibble, group_by, summarise, n_distinct
>>>
>>> data = tibble(
...     CLIENT_CODE=[1,1,2,1,2,2,3],
...     YEAR_MONTH=[201301,201301,201301,201302,201302,201302,201302]
... )
>>>
>>> data >> group_by(f.YEAR_MONTH) >> summarise(n=n_distinct(f.CLIENT_CODE))
   YEAR_MONTH       n
      <int64> <int64>
0      201301       2
1      201302       3

什么是“dplyr 语法”?您可以add对它的(权威)引用(用于上下文)吗? (但没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的。)