【问题标题】:Pandas: how to create a running count column?Pandas:如何创建运行计数列?
【发布时间】:2018-07-13 07:48:24
【问题描述】:

我有一个表单的纯文本文件(我添加的列标题)

CASE        Diagnosis
  S1 no diagnosis
  S2 fungus
     squamous lesion
  S3 fungus
  S4 squamous lesion
     glandular lesion
     atypia

我想堆叠和取消堆叠多个诊断的病例,所以我想要

CASE DxN         Diagnosis
  S1 A   no diagnosis
  S2 A   fungus   
     B   squamous lesion
  S3 A   fungus
  S4 A   squamous lesion
     B   glandular lesion
     C   atypia

CASE                 A                 B       C
  S1 no diagnosis
  S2 fungus             squamous lesion
  S3 fungus
  S4 squamous lesion    glandular lesion  atypia

如何制作 DxN 子系列?计数不应大于 F。即使有 10,000 个可能的答案,每个案例也不会超过 6 个,因此不超过 6 列。我只想“病例 S1 的诊断 A 是什么,病例 S1 的诊断 B 是什么,病例 S1 的诊断 3 是什么?”我不希望每一个可能的答案都有一个专栏。

【问题讨论】:

  • 当你说“我有”然后你粘贴那个东西时,不清楚你实际上有什么对象。我可以想象你的意思是几件事之一。如果您粘贴一些我们可以准确地重新创建您的数据的内容,那将是最好的。假设您的对象是一个名为's' 的熊猫系列。您可以粘贴来自s.to_dict()的结果
  • 好的,谢谢,已更新。从纯文本文件开始。
  • 这是一个制表符分隔的文本文件吗?如果不是,很好奇,它最初是如何制作的?
  • 它是由名为 CoPath 的 MUMPS 程序生成的。有些诊断包含逗号,所以我最初使用管道作为分隔符,但后来在 vim 中添加它。

标签: python pandas reshape


【解决方案1】:

这是你需要的吗?

    df=df.replace('',np.nan).ffill()
    df.assign(DxN=df.groupby('CASE').cumcount()).set_index(['CASE','DxN']).Diagnosis.unstack(fill_value='')
    Out[709]: 
    DxN                0                1
    CASE                                 
    S1       nodiagnosis                 
    S2            fungus   squamouslesion
    S3            fungus                 
    S4    squamouslesion  glandularlesion

【讨论】:

  • 赞成这个答案比我的更聪明。或许问的地方不对,但是这种操作拆分成多行不是更好吗?除了违反 python 风格准则外,人类更容易理解和适应。只是一个问题!
  • @jp_data_analysis 是的,当我写下我的工作脚本时,我总是将其分解为多行(易于调试和设置块),但似乎 SOer 对一个班轮解决方案上瘾 :-)
  • 一旦我发现我有一堆非打印空白,它就起作用了。谢谢!
  • @Niels yw:-) 快乐编码
【解决方案2】:

这是一种方法,从您拥有的文本格式的数据开始:

import pandas as pd
import numpy as np

df = pd.DataFrame([['S1', 'no diagnosis'],
                   ['S2', 'fungus'],
                   ['', 'squamous lesion'],
                   ['S3', 'fungus'],
                   ['S4', 'squamous lesion'],
                   ['', 'glandular lesion']],
                  columns=['CASE', 'Diagnosis'])

# front fill CASE series
df.CASE = df.CASE.replace('', np.nan).ffill()

# pivot data
df = pd.pivot_table(df, index=['CASE'], values=['Diagnosis'],
                    aggfunc=lambda x: list(x)).reset_index()

# split columns of lists into separate columns
df = pd.concat([df[['CASE']], pd.DataFrame(df['Diagnosis'].values.tolist())], axis=1)

#   CASE                0                 1
# 0   S1     no diagnosis              None
# 1   S2           fungus   squamous lesion
# 2   S3           fungus              None
# 3   S4  squamous lesion  glandular lesion

【讨论】:

    【解决方案3】:

    您可以创建一个列,其中包含每个病例的诊断总数。更多详情见此帖:SQL-like window functions in PANDAS: Row Numbering in Python Pandas Dataframe

    使用此示例数据:

    df = pd.DataFrame([
        {'Case': 'S1', 'Diagnosis': 'no diagnosis'},
        {'Case': 'S2', 'Diagnosis': 'fungus'},
        {'Case': 'S2', 'Diagnosis': 'squamous lesion'}
    ])
    

    此脚本将为您提供运行总数:

    df['DxN'] = df.sort_values(['Case'], ascending=[1]).groupby('Case').cumcount() + 1
    

    【讨论】:

      猜你喜欢
      • 2022-09-30
      • 2016-01-12
      • 2021-09-07
      • 2018-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      相关资源
      最近更新 更多