首页 > 解决方案 > 尝试根据每行另一列行的值拆分数据框列

问题描述

我有一些带有考试成绩信息的 ID 编号(df 索引)。每个测试都由子测试组成。所有的 SubTest 分数都在同一个字段中,并且还有一个字段告诉您测试类型(即分隔符)。比如说我有GRE。GRE 有三个子测试:Verbal、Analytical Writing 和 Quantitative。一个字段具有测试类型 (GRE),另一个字段具有一个字段中的测试分数值(GRE 语言 156.0/170.0 GRE 分析写作 4.5/6.0 GRE 定量 157.0/170.0)。此数据集中具有相同结构的多个其他测试。我想使用“测试类型”列作为“测试分数值”字段上的 .split 方法的分隔符,并具有 expand = True 但它永远不会工作......我不断收到一个关键错误。

我尝试了很多不同的方法(其中许多来自 stackoverflow 上的类似问题,与我的问题不完全匹配):

1.)

df[['Score1', 'Score2', 'Score3','Score4','Score5']] = [x.split(df['Delimiter'], n = 5, expand=True) for x in df['Test Score Values']] 

这导致了“KeyError:分隔符”

2.)

df[['Score1', 'Score2', 'Score3','Score4','Score5']] = df.apply(lambda x: x['Test Score Values'].str.split(df['Delimiter'], n = 5, expand=True))

这导致“KeyError: ('Test Score Values', 'occured at index ID')”

3.)

df[['Score1', 'Score2', 'Score3','Score4','Score5']] = df['Test Score Values'].split(df['Delimiter'], n = 5, expand=True)

这导致“AttributeError:'Series'对象没有属性'split'”

4.)

df['Test Score Values'].apply(lambda x: x.split(x['Delimiter'],expand=True))

这导致“TypeError:字符串索引必须是整数”

我不断收到错误,但我想得到的是,与开头的 GRE 示例保持一致,类似于以下内容。

ID     Delimiter               TestScoreValues
1         GRE        GRE Verbal 156.0/170.0 GRE Analytical Writing 4.5/6.0 GRE Quantitative 157.0/170.0      

Score1                   Score2                                    Score 3
Verbal 156.0/170.0      Analytical Writing 4.5/6.0           Quantitative 157.0/170.0    

然后我想进一步分解它们,但解决这个拆分将是一个很好的第一步,因为之后我可以在不同分数内的空间上拆分。

有人可以帮忙吗?

标签: pythonstringpandassplit

解决方案


对于高度具体的操作,我推荐使用for循环,因为它们具有灵活性和可读性(尽管我会强调这并不是自动执行此类操作的最优化方式)。

首先,初始化您的数据框:

import pandas as pd

s = {'Test Type':'GRE',
     'Test Score':'GRE Verbal 156.0/170.0 GRE Analytical Writing 4.5/6.0 GRE Quantitative 157.0/170.0',
    }

df = pd.DataFrame([s])

print(df.head())
#
#                                          Test Score Test Type
# 0  GRE Verbal 156.0/170.0 GRE Analytical Writing ...       GRE

接下来,遍历您的 df 并执行必要的字符串操作:

new_values = []

for idx, row in df.iterrows():
  scores = row['Test Score'].split(row['Test Type'])
  for s in scores:
    # You don't want the blank items
    if s!='':
      s = s.strip().split()
      # get the section and the score for each
      section, score_actual = ' '.join(s[:-1]),s[-1]
      new_values.append({
          'Test': row['Test Type'],
          'Section':section,
          'Score': score_actual})

df_new = pd.DataFrame(new_values)
print(df_new.head())
#
#          Score             Section Test
# 0  156.0/170.0              Verbal  GRE
# 1      4.5/6.0  Analytical Writing  GRE
# 2  157.0/170.0        Quantitative  GRE

您可以更进一步,开始将每一行降低到其百分比分数,或者创建一个新表,其中包含每次考试每个部分的最高分数,但我将把它留给您。


推荐阅读