我有这样的数据.

Record number level 1 person level 2 person date time spent on job
1 Tim David, Cameron Green - (Division 1) 01/01/2023 5
2 Tim David - (Division 1) Mitch, Eli Kin Marsh - (Division 2) 02/02/2023 3
3 David Warner - (Division 2), Travis Head - (Division 3) 03/04/2023 1
4 Cameron Green - (Division 1) Tim David - (Division 1) 07/01/2023 2

最终目标是获得每个人每月花在工作上的总时间,按部门分类.这与人的级别无关.结果应该类似于:

Division Person Month time spent on job
Division 1 Tim David Jan-23 7
Division 1 Tim David Feb-23 3
Division 1 Cameron Green Jan-23 7
Division 2 Mitch, Eli Kin Marsh Feb-23 3
Division 2 David Warner Apr-23 1
Division 3 Travis Head Apr-23 1

要做到这一点,首先,我正在努力清理"2级人员"一栏.在本栏中,记录1表示1组中都有两个人.一个人是Tim David,另一个是Cameron Green.在记录2中,只有一个人Mitch,Eli Kin Marsh,他在2组.在3组中,有两个人在两个不同的组.大卫·华纳在2区,特拉维斯·海德在3区.在唱片4中,只有一个人蒂姆·大卫在1区.

  1. 我正在try 创建一个新的专栏,以捕捉特定记录中涉及的所有人.在这样做的时候,我无法拆分"2级人员"一栏中的名字.例如,在记录1和记录2中,我很难用逗号分隔,因为在记录2中,即使只有一个人,也有一个逗号分隔姓氏和其他名字.所以我想要记录1的名单是记录2的[‘Tim David’,‘Cameron Green’][‘Mitch Eli Kin Marsh’].

这就是我try 这一部分的方式:

def split_names(row):
string = row['level 2 person']

pattern = '([\w\s,-]+)'

names = re.split(pattern, string) 

name_list = list()

for name in names:
    replacements = [('-', ''), ('(', ''), (')', '')]

    for char, replacement in replacements:
        if char in name:
            name= name.replace(char, replacement)
    name_list.append(name)        

while("" in name_list): # remove empty elements
    name_list.remove("")
    
return name_list

df['names'] = df.apply(split_names,axis=1)
  1. 然后我也想为那些没有的人分配部门.如果多个人在同一部门,就会发生这种情况.例如,在记录1中.因此,我正在考虑创建另一个列,其中每个元素都对应于该人员所属的部门.因此,对于记录1,该列表将是[‘分区1’,‘分区1’]

推荐答案

既然Mitch是"1个单词",那么"2个单词"必须出现在逗号之前才能解决这个问题吗?

这可以用regex module from pypi来完成,因为它支持可变长度的回溯断言.

>>> import regex
>>>
>>> pattern = r'(?<=[^,\s]+\s+[^,\s]+), '
>>> regex.split(pattern, 'I, am all one name - (Division 2)')
['I, am all one name - (Division 2)']
>>> regex.split(pattern, 'I am, not all one name - (Division 2)')
['I am', 'not all one name - (Division 2)']

(您也可以在不使用正则表达式的情况下实现这一点,方法是只拆分逗号并将"1 word"单元格与其相邻单元格合并.)

修改您的示例:

def split_names(cols):
     # must be 2 "words" before comma space 
     pattern = r'(?<=[^,\s]+\s+[^,\s]+), '
    
     people = {}
     
     for names in cols:
         names = regex.split(pattern, names)

         if names == ['']: 
             continue 
             
         same_division = False
         level = {}
             
         for name in names:
             if ' - ' in name:
                name, division = name.split(' - ')
                division = division.strip('()')
             else:
                division = None
                same_division = True
               
             level[name] = division
 
         if same_division:
             level = dict.fromkeys(level, division)
             
         people.update(level)
            
     return [
         {'Division': division, 'Person': person} for person, division in people.items()
     ]

用法示例:

columns = ['level 1 person', 'level 2 person']
df[columns].apply(split_names, axis=1)
0    [{'Division': 'Division 1', 'Person': 'Tim Dav...
1    [{'Division': 'Division 1', 'Person': 'Tim Dav...
2    [{'Division': 'Division 2', 'Person': 'David W...
3    [{'Division': 'Division 1', 'Person': 'Cameron...
dtype: object

您可以使用.explode.join将结果转换为列.

columns = ['level 1 person', 'level 2 person'] 

df = (
   df.drop(columns=columns)
     .join(df[columns].apply(split_names, axis=1).rename('People'))
     .explode('People', ignore_index=True)
)

df = df.join(pd.DataFrame(df.pop('People').values.tolist())) 
   Record number       date  time spent on job    Division                Person
0              1 2023-01-01                  5  Division 1             Tim David
1              1 2023-01-01                  5  Division 1         Cameron Green
2              2 2023-02-02                  3  Division 1             Tim David
3              2 2023-02-02                  3  Division 2  Mitch, Eli Kin Marsh
4              3 2023-03-04                  1  Division 2          David Warner
5              3 2023-03-04                  1  Division 3           Travis Head
6              4 2023-07-01                  2  Division 1         Cameron Green
7              4 2023-07-01                  2  Division 1             Tim David

Python相关问答推荐

Tokenizer Docker:无法为Tokenizer构建轮子,这是安装pyproject.toml项目所需的

将C struct 的指针传递给Python中的ioctel

customtkinter中使用的这个小部件的名称是什么

GEKKO:已知延迟的延迟系统的参数估计

无法导入已安装的模块

使用Python和PRNG(不是梅森龙卷风)有效地生成伪随机浮点数在[0,1)中均匀?

当值是一个integer时,在Python中使用JMESPath来验证字典中的值(例如:1)

如何使用矩阵在sklearn中同时对每个列执行matthews_corrcoef?

更改matplotlib彩色条的字体并勾选标签?

如何自动抓取以下CSV

对某些列的总数进行民意调查,但不单独列出每列

大小为M的第N位_计数(或人口计数)的公式

log 1 p numpy的意外行为

Polars:用氨纶的其他部分替换氨纶的部分

如何使用pytest来查看Python中是否存在class attribution属性?

利用Selenium和Beautiful Soup实现Web抓取JavaScript表

Odoo 16使用NTFS使字段只读

什么是最好的方法来切割一个相框到一个面具的第一个实例?

* 动态地 * 修饰Python中的递归函数

pysnmp—lextudio使用next()和getCmd()生成器导致TypeError:tuple对象不是迭代器''