【问题标题】:Python pandas splinting strings, adding rows, different for each columnPython pandas夹板字符串,添加行,每列不同
【发布时间】:2020-01-19 23:18:57
【问题描述】:

我希望在我拔掉所有头发之前,有比我更多知识的人提供一些智慧。

我有一个看起来像这样的数据框

Date    Unit    Length  AM/PM   unit_new
5   Monday\r13 January  12345H\rEngineering - Unit 1: Engineering Principles\r23456H\rHealth and Social Care - Unit 2: Working in Health\rand Social Care   2h 00m\r1h 30m  morning
6   Tuesday\r14 January 34567H\rBusiness/Enterprise and Entrepreneurship -\rUnit 3: Personal and Business Finance\r12345L\rApplied Human Biology - Unit 1: Principles of\rHuman Biology\r23456K\rConstruction and the Built Environment -\rUnit 1: Construction Principles  2h 00m\r1h 30m\r1h 30m  morning
7   Wednesday\r15 January   34567H/1C\rApplied Science/Forensic and Criminal Investigation\r- Unit 1: Principles and Applications of Science I -\rChemistry\r12345H\rSport and Exercise Science - Unit 1: Sport and Exercise\rPhysiology    0h 40m\r1h 30m  morning

现在我遇到的问题是,'Unit' 列的每一行都有多条记录的数据,但是一行的记录数并不一致。 “长度”列与“单位”列具有相同的设置。 “日期”和“上午/下午”列有一个条目。

这张图片更好地解释了这个问题。第 5 行有两条记录,一条用于工程,一条用于 HSC,长度列如下。两条记录的“日期”和“上午/下午”相同。第 6 行有三个记录,第 7 行有两个。

现在我要做的是将每条记录拆分到自己的行中。在尝试这样做时,我尝试了许多不同的方法,但没有取得多大进展。

方法思路一 我的第一个想法是尝试在相关行下添加新行,并从“单位”和“长度”列中提取数据,同时从“日期”和“上午/下午”列中复制数据。这被证明是一种技巧,因为插入 df 的中间会更复杂。

方法思路二 接下来我想将行附加到 df 的底部并稍后排序。

所以我写了一个函数来计算每行的记录数并输出到一个系列。

def code_count_func():
    code_count = df.Unit.str.count('\d{5}\w').subtract(+1)
    # drop na's to stop error
    code_count.dropna(inplace = True) 
    # converting to int 
    code_count = code_count.iloc[0:].astype(int)

下面的代码是我目前正在尝试的,它在一个名为“unit_new”的新列中拆分为一个字符串列表,但正则表达式并没有完全按照我的彩色图像捕获。

for index, row in code_count_func().iteritems():
    df['unit_new'] = df.Unit.str.split('(\d{5}\w)')

第二个问题是我也不确定如何完成程序。我在考虑使用DataFrame.explode 方法,但我不确定如何在“单位”和“长度”列上使用它,但只是从“日期”和“上午/下午”列复制。

谁能给我一些关于如何使用爆炸方法或类似方法的指导。另外,如果有人能够帮助我的正则表达式,请。

关于正则表达式问题的更多信息。因此,与“单位”列中的模式一致的一件事是五位数字和一个字母,例如12345K 用于每条新记录的开头。所以看看第 5 行,我想得到这个:-

12345H\r工程学 - 第 1 单元:工程学原理\r 23456H\r健康和社会关怀 - 第 2 单元:从事健康\和社会关怀

我尝试了很多模式,但都没有成功。

所需输出

【问题讨论】:

  • 想要的输出是什么样的?

标签: python regex pandas dataframe


【解决方案1】:

这可能会起作用,并且使用更精致的正则表达式可能会更好。我的列可能不在复制/粘贴过程中,但逻辑应该是正确的

获取单位

df['Unit'] = df['Unit'].str.split('(.+?(?=\d{5}))')

获取长度

lengths = df['AM/PM'].str.split(r'\\r').explode()

分解单元,从正则表达式中删除空条目并将长度连接回数据帧

df = pd.concat([df.explode('Unit').query("Unit != ''"), lengths], axis=1)

            Date           ...                                               Unit   AM/PM
5     Monday\r13  January  ...  12345H\rEngineering - Unit 1: Engineering Prin...  2h 00m
5     Monday\r13  January  ...  23456H\rHealth and Social Care - Unit 2: Worki...  1h 30m
6    Tuesday\r14  January  ...  34567H\rBusiness/Enterprise and Entrepreneursh...  2h 00m
6    Tuesday\r14  January  ...  12345L\rApplied Human Biology - Unit 1: Princi...  1h 30m
6    Tuesday\r14  January  ...  23456K\rConstruction and the Built Environment...  1h 30m
7  Wednesday\r15  January  ...  34567H/1C\rApplied Science/Forensic and Crimin...  0h 40m
7  Wednesday\r15  January  ...  12345H\rSport and Exercise Science - Unit 1: S...  1h 30m

【讨论】:

  • 天才,它有效!不得不爱熊猫。我理解一些逻辑,但不是全部。我想知道为什么我不能这样做units = df['Unit'].str.split('(.+?(?=\d{5}))').explode().query("Unit != ''") lengths = df['Length'].str.split('\\r').explode() df = pd.concat([units, lengths], axis=1) 或这个 df['Unit'] = df['Unit'].str.split('(.+?(?=\d{5}))') df['Length'] = df['Length'].str.split('\\r') df = pd.concat([df.explode('Unit').query("Unit != ''"), df.explode('Length').query("Length != ''")], axis=1)
  • explode 更改了原始df 的形状,因此您不能只是重新分配它。您可以将它们分开并在最后连接,但随后您会丢失其他列。如果可行,请accept the answer 这样可以关闭
猜你喜欢
  • 1970-01-01
  • 2013-11-30
  • 2022-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2020-10-18
  • 2019-05-07
相关资源
最近更新 更多