Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';这是在pandas中执行聚合和重命名操作的惯用方法_Python_Pandas - Fatal编程技术网

Python 什么';这是在pandas中执行聚合和重命名操作的惯用方法

Python 什么';这是在pandas中执行聚合和重命名操作的惯用方法,python,pandas,Python,Pandas,例如,如何在pandas中执行以下R data.table操作: PATHS[,.( completed=sum(exists), missing=sum(not(exists)), total=.N, 'size (G)'=sum(sizeMB)/1024), by=.(projectPath, pipelineId)] 也就是说,按projectPath和pipelineId分组,聚合一些列 可能使用自定义函数,然后重命名生成的列 输出应该是没有层次索引的数据帧,例如:

例如,如何在pandas中执行以下R data.table操作:

PATHS[,.( completed=sum(exists), missing=sum(not(exists)), total=.N, 'size (G)'=sum(sizeMB)/1024), by=.(projectPath, pipelineId)]
也就是说,按
projectPath
pipelineId
分组,聚合一些列 可能使用自定义函数,然后重命名生成的列

输出应该是没有层次索引的数据帧,例如:

                      projectPath pipelineId completed missing size (G)
/data/pnl/projects/TRACTS/pnlpipe          0      2568       0 45.30824
/data/pnl/projects/TRACTS/pnlpipe          1      1299       0 62.69934

您可以使用
groupby.agg

df.groupby(['projectPath', 'pipelineId']).agg({
        'exists': {'completed': 'sum', 'missing': lambda x: (~x).sum(), 'total': 'size'},
        'sizeMB': {'size (G)': lambda x: x.sum()/1024}
    })

样本运行:


更新:如果确实要自定义聚合而不使用不推荐的嵌套字典语法,则始终可以使用
groupby.apply
并从每个组返回一个序列对象:

df.groupby(['projectPath', 'pipelineId']).apply(
    lambda g: pd.Series({
            'completed': g.exists.sum(),
            'missing': (~g.exists).sum(),
            'total': g.exists.size,
            'size (G)': g.sizeMB.sum()/1024 
        })
).reset_index()

我相信新的0.20更“惯用”的方式是这样的(嵌套字典的第二层基本上被附加的
.rename
方法所取代):

…(completed=sum(exists),missing=sum(not(exists)),total=.N,‘size(G)’=sum(sizeMB)/1024),by=(projectPath,pipelineId)]…
在R中,变为

编辑:在
pd.DataFrame.groupby()中使用
as_index=False
,以防止在最终df中使用多索引

df.groupby(['projectPath', 'pipelineId'], as_index=False).agg({
    'exists': 'sum', 
    'pipelineId': 'count', 
    'sizeMB': lambda s: s.sum() / 1024
}).rename(columns={'exists': 'completed', 
                   'pipelineId': 'total',
                   'sizeMB': 'size (G)'})
然后,我可能会添加另一行作为“exists”->“missing”的倒数:

df['missing'] = df.total - df.completed

作为Jupyter笔记本测试中的一个例子,下面是一个模拟目录树,由
pd.read_csv()
导入一个Pandas数据帧,其中包含46条管道路径,我稍微修改了这个例子,使其具有1000-100k核苷酸碱基之间的DNA字符串形式的随机数据,而不是创建Mb大小的文件。尽管如此,非离散gigabases仍在计算中,在
df.agg
调用中可用的聚合
pd.Series
对象上使用NumPy的
np.mean()
,但
lambda s:s.mean()
将是更简单的方法

e、 g

df_paths.groupby(['TRACT', 'pipelineId']).agg({
    'mean_len(project)' : 'sum',
    'len(seq)' : lambda agg_s: np.mean(agg_s.values) / 1e9
}).rename(columns={'len(seq)': 'Gb',
                   'mean_len(project)': 'TRACT_sum'})
其中,“TRACT”是目录树中比“pipelineId”高一级的类别,因此在本例中,您可以看到共有46个唯一管道-2个“TRACT”层AB/AC x 6个“pipelineId”/“project”的x 4个二进制组合00、01、10、11(减去GNU并行生成第三个topdir的2个项目;见下文)。因此,在新的agg中,统计数据将项目水平的平均值转换为每个区域内所有相应项目的总和


您是否有粘贴在该问题中的示例输入数据框?非常好的示例。很好+1@ScottBoston谢谢。我想接受这个答案,但他们很快就会反对.agg()中的嵌套字典:你能在你的groupby中使用
as\u index=False
,这样你以后就不需要
droplevel
调用了吗?当然,您可以将这两列作为对
groupby
对象的两个单独调用,并将每个结果分配给
df
对象中自己的列,从而消除了对嵌套字典的需要,即使它没有这样干净answer@scnerd真是个好主意!我在下面编辑了我的答案,以更正非层次/非默认索引
df_paths.groupby(['TRACT', 'pipelineId']).agg({
    'mean_len(project)' : 'sum',
    'len(seq)' : lambda agg_s: np.mean(agg_s.values) / 1e9
}).rename(columns={'len(seq)': 'Gb',
                   'mean_len(project)': 'TRACT_sum'})
df_paths = pd.read_csv('./data/paths.txt', header=None, names=['projectPath'])
# df_paths['projectPath'] = 
df_paths['pipelineId'] = df_paths.projectPath.apply(
    lambda s: ''.join(s.split('/')[1:5])[:-3])
df_paths['TRACT'] = df_paths.pipelineId.apply(lambda s: s[:2])
df_paths['rand_DNA'] = [
    ''.join(random.choices(['A', 'C', 'T', 'G'], 
                           k=random.randint(1e3, 1e5)))
    for _ in range(df_paths.shape[0])
]
df_paths['len(seq)'] = df_paths.rand_DNA.apply(len)
df_paths['mean_len(project)'] = df_paths.pipelineId.apply(
    lambda pjct: df_paths.groupby('pipelineId')['len(seq)'].mean()[pjct])
df_paths