python - 如何列出与每项事件相关的所有姓名和年龄

标签 python pandas

我有一个数据框,其中包含有关哪些人参加每项事件的信息。不幸的是,每条信息可以放置在多个不同的位置。也就是说,一行可以为许多不同的人提供信息。列名称如下:

['Name', 'Activity', 'Name.0', 'Age.0', 'Activity.0', 'Name.1', 'Age.1', 'Activity.1', 'Name.2', 'Age.2', 'Activity.2', 'Name.3', 'Age.3',  'Activity.3', 'Name.4', 'Age.4', 'Activity.4']

对于每项事件,我想列出与其相关的所有人员及其年龄(如果提供了该信息)。最终我想为每个事件制作一张表。我怎样才能做到这一点?

感觉我需要首先处理所有 .* 列名称,然后以某种方式处理 groupby Activity,但我不知道该怎么做。

这是使用df.sample(5).to_dict()输出的一些匿名数据

{'Activity': {0: 'Audi', 1: 'Carn', 2: 'Pop-', 3: 'Samb', 4: 'Pre-'},
 'Activity.0': {0: 'Samb', 1: 'Pre-', 2: 'nan', 3: 'Samb', 4: 'Pre-'},
 'Activity.1': {0: 'Samb', 1: 'Audi', 2: 'nan', 3: 'Samb', 4: 'nan'},
 'Activity.2': {0: 'Pre-', 1: 'Audi', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Activity.3': {0: 'nan', 1: 'Carn', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Activity.4': {0: 'nan', 1: 'Carn', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Age.0': {0: '18+', 1: 'Under 5', 2: '11', 3: '11', 4: 'Under 5'},
 'Age.1': {0: '11', 1: 'Under 5', 2: '11', 3: 17, 4: '18+'},
 'Age.2': {0: '11', 1: '18+', 2: 'nan', 3: '18+', 4: 'nan'},
 'Age.3': {0: 'Under 5', 1: '18+', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Age.4': {0: 'nan', 1: '18+', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Name': {0: 'Jess', 1: 'Tama', 2: 'Beki', 3: 'Havi', 4: 'Dror'},
 'Name.0': {0: 'Sam ', 1: 'Lila', 2: 'nan', 3: 'Joel', 4: 'Emil'},
 'Name.1': {0: 'Zipp', 1: 'Marg', 2: 'nan', 3: 'Solo', 4: 'Ari '},
 'Name.2': {0: 'Reub', 1: 'Joan', 2: 'nan', 3: 'Sami', 4: 'nan'},
 'Name.3': {0: 'Shev', 1: 'John', 2: 'nan', 3: 'nan', 4: 'nan'},
 'Name.4': {0: 'nan', 1: 'Edwa', 2: 'nan', 3: 'nan', 4: 'nan'}}

在此示例中,我们以名为“Audi”的事件为例。唯一这样做的人是“Jess”(无年龄)、“Marge”(5 岁以下)和“Joan”(18 岁以上)。对于事件“Samb”,与其相关的人是“Havi”(无年龄)、“Sam”(18 岁以上)、“Joel”(11)、“Zipp”(11)和“Solo”(17)。我希望每项事件都有同样的效果。

最佳答案

这对你有用:

activities = {}
# function for Activity, Name
def add_details_for_activity(row):
    global activities
    if pd.notna(row[1]) and pd.notna(row[0]) and row[1] != 'nan' and row[0] != 'nan':
        if activities.get(row[0]) is not None:
            activities[row[0]].append(row[1])
        else:
            activities[row[0]] = [row[1]]

# function for Activity.#, Name.#, age.#   
def add_details_for_activities(row):
    global activities
    if pd.notna(row[1]) and pd.notna(row[0]) and row[1] != 'nan' and row[0] != 'nan':
        if activities.get(row[0]) is not None:
            if pd.notna(row[2]) and row[2] != 'nan':
                activities[row[0]].append((row[1], row[2]))
            else:
                activities[row[0]].append(row[1])
        else:
            print(row[0])
            if pd.notna(row[2]) and row[2] != 'nan':
                activities[row[0]] = [(row[1], row[2])]
            else:
                activities[row[0]] = [row[1]]


df[['Activity', 'Name']].apply(add_details_for_activity, axis = 1)
for i in range(5):
    df[['Activity.'+str(i), 'Name.'+str(i), 'Age.'+str(i)]].apply(add_details_for_activities, axis = 1)

示例输出为:

{'Audi': ['Jess', ('Marg', 'Under 5'), ('Joan', '18+')],
 'Carn': ['Tama', ('John', '18+'), ('Edwa', '18+')],
 'Pop-': ['Beki'],
 'Samb': ['Havi',
  ('Sam ', '18+'),
  ('Joel', '11'),
  ('Zipp', '11'),
  ('Solo', 17)],
 'Pre-': ['Dror', ('Lila', 'Under 5'), ('Emil', 'Under 5'), ('Reub', '11')]}

关于python - 如何列出与每项事件相关的所有姓名和年龄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60278675/

相关文章:

python - 在pytest中使用参数的笛卡尔积进行参数化测试

python - 根据标题列表创建聚合列

python - 具有滞后值(value)的条件产品的 Pandas cumsum?

python - Pandas 仅将新值从一个 df 插入到另一个有条件的

python - 寻找 PHP 的 str_split() 替代品

python - 在上下文管理器中装饰任何 python 函数

python - 在fabric 2中如何运行不同的用户?

python - 无法使用 python PDFKIT 错误 : "No wkhtmltopdf executable found:" 创建 pdf

python - 将 matplotlib 图例保存为单独的图像

python - 如何将现有 Pandas DataFrame 的所有值设置为零?