【问题标题】:Python: Split string conditional on elements in other listPython:根据其他列表中的元素拆分字符串
【发布时间】:2016-09-08 11:35:50
【问题描述】:

所以我有一个按以下方式构建的 pandas 数据框:

In: df.head(1)
Out:
Individual      Employer                    EmployerState       BranchesState                    BranchesNr
872570          (4210, 7463, 23130, 133752) (MN, GA, NY, AZ)    (MN, AZ, GA, AZ, NY, AZ, AZ)    (0, 1, 0, 1, 0, 1, 0)

现在我打算做的是拆分所有多个雇主信息并为每个雇主-雇员对创建一个记录,如下所示:

Individual       Employer       EmployerState   BranchesState       BranchesNr
872570           4210           MN              MN, AZ              0, 1
872570           7463           GA              GA, AZ              0, 1
872570           23130          NY              NY, AZ              0, 1
872570           133752         AZ              AZ                  0

目前,我可以通过应用以下代码为 Individual、Employer 和 EmployerState 列执行此操作:

rows = [] # Store individuals in empty array
for _, row in indv_sub.iterrows():

# If there are multiple employers
# Example:
# Individual | Employer      =>         Individual | Employer
# 123        | (XY, AB)                 123        | XY
#                                       123        | AB

    if len(str(row['Employer']).split(','))>1:
        # split the individual record into as many employers as an individual has
        [rows.append(
                 [row['Individual'], 
                  m.replace('(','').replace(')',''),
                  l.replace('(','').replace(')',''),
                  row['BranchesState']]) 
                  for m,l in zip(row['Employer'].split(','),row['EmployerState'].split(','))]
    else:
        # just add the single employer
        rows.append([row['Individual'], row['Employer'], row['EmployerState'], row['BranchesState']])

indv_relevant = pd.DataFrame(rows,columns=('Individual','Employer','EmployerState','BranchesState'))
indv_relevant = indv_relevant.convert_objects(convert_numeric=True)   

这很好用,但我无法拆分 BranchesState 列。我添加了一个 BranchesNr 字段,该字段用 0 表示下一个雇主的分支机构。所以考虑这个例子:

 Employer           BranchesState                   BranchesNr
 (MN, GA, NY, AZ)   (MN, AZ, GA, AZ, NY, AZ, AZ)    (0, 1, 0, 1, 0, 1, 0)

第一个到值是 0,1 后跟一个 0,表示直到第二个位置的所有分支都属于第一个雇主。

list(row['BranchesState'].split(','))[:2] # would be attributable to the first employer

接下来是位置 3 到 4,属于第二个雇主,以此类推。我不太确定如何很好地实现它。有什么想法或建议吗?

P.S:这些字段是字符串,而不是看起来的元组/列表。另外0,1,0只是一个例子,一些序列是0,1,2,0,1,0,1,2,3,4等。

为了包含更多的数据变化,以下是 10 次观察的示例:

{u'BrnchOfLoc_FirmNr': {1490: u'(0, 0)', 第1498章 第1594章 1618: 你'(0, 0, 0)', 第1632章 第1633章 第1687章 第1738章 第1783章 第1793章 u'BrnchOfLoc_state': {1490: u'(CA, CA)', 第1498章 第1594章 第1618章 1632:你'(纽约,纽约)', 第1633章 第1687章 第1738章 1783:你'(MS,MS,LA)', 第1793章 u'CrntEmp_orgPK': {1490: u'(13572, 144875)', 第1498章 1594: 你'(519, 162200)', 1618: 你'(23131, 111532, 113269)', 1632: 你'(6627, 118660)', 1633: 你'(6413, 131406)', 第1687章 1738: 你'(23131, 105698)', 1783:你'(159778,160431)', 1793: 你'(6413, 128859)'}, u'CrntEmp_state': {1490: u'(CA, CA)', 第1498章 第1594章 1618:你'(纽约,加利福尼亚,加利福尼亚)', 1632:你'(纽约,纽约)', 第1633章 第1687章 第1738章 第1783章 第1793章 u'Info_indvlPK':{1490:u'731003', 1498:你'29443', 1594:你'708024', 1618:你'707057', 1632:你'830502', 1633:你'854101', 第1687章 第1738章 1783:你'734227', 1793:你'849856'}, 'NumberEmployer': {1490: 2, 1498:2, 1594:2, 1618:3, 1632:2, 1633:2, 1687:2, 1738:2, 1783:2, 1793: 2}}

【问题讨论】:

  • 您能否提供一个较小的示例来准确显示您希望针对给定输入接收的输出?我不完全清楚分支应该如何工作,完整的样本会有所帮助。此外,将示例数据框的代码放入其中有助于人们回答。
  • 我使列名更易于解释并扩展了示例。这有帮助吗?
  • df.head().to_dict('list') 怎么样?最好能看到数据的更多变化。
  • 在我的帖子中添加了 10 条意见。希望有帮助。感谢您抽出宝贵时间!

标签: python string pandas split conditional


【解决方案1】:

我认为这可以让您接近那里,但我仍然不清楚拆分 EmployerState 的规则。也许您可以添加一个额外的示例?

df = pd.DataFrame(
    {'BranchesNr': ['(0, 1, 0, 1, 0, 1, 0)', 
                    '(0, 1, 0, 1, 0, 1, 0)'],
     'BranchesState': ['(MN, AZ, GA, AZ, NY, AZ, AZ)',
                       '(MN, AZ, GA, AZ, NY, AZ, AZ)'],
     'Employer': ['(4210, 7463, 23130, 133752)',
                  '(4210, 7463, 23130, 133752)'],
     'EmployerState': ['(MN, GA, NY, AZ)',
                       '(MN, GA, NY, AZ)'],
     'Individual': [872570, 872570]})

df['Employer'] = df.Employer.str.findall('(\d+)')
df['EmployerState'] = df.EmployerState.str.findall('(\w+)')
df['BranchesState'] = df.BranchesState.str.findall('(\w+)')
df['BranchesNr'] = df.BranchesNr.str.findall('(0|1)+')

indices = [[0] + [n for n, flag in enumerate(branches, 1) if flag == '1'] 
           for branches in df.BranchesNr]

>>> [(row. Individual, row.Employer[n], row. EmployerState[n]) 
     for idx, row in df.iterrows() 
     for n in range(len(row.Employer))]


[(872570, '4210', 'MN'),
 (872570, '7463', 'GA'),
 (872570, '23130', 'NY'),
 (872570, '133752', 'AZ'),
 (872570, '4210', 'MN'),
 (872570, '7463', 'GA'),
 (872570, '23130', 'NY'),
 (872570, '133752', 'AZ')]

【讨论】:

  • 是的,这是可行的,但是当元素为零时,BranchesStates 应该在 BranchesNr 中的相应位置拆分,除了第一个 0。所以对于我提到的示例,BranchesStates 应该拆分为 4 部分: [:2]、[2:4]、[4:6]、[6]。这更有意义吗?所以从第一个 0 到第二个 0,从第二个零到第三个零,等等。
  • 我相信indices 变量表示应该何时发生拆分,但我仍然不确定这个逻辑。你能提供一个更多样化的例子吗?
  • 因此假设有两个雇主 A 和 B,他们各有一个分支机构:A1 和 B1。所以数据看起来像这样:Individual (A,B) (A1,B1) (0,0) 但我不一定知道哪个分支机构属于哪个雇主,可能是 A1 和 B1 实际上属于 A。所以 (0,0) 表示第一个分支属于第一个雇主,第二个分支属于第二个雇主。如果 BranchNr 的值为 (0,1),我现在会认为两个分支都属于 A。这样更清楚吗?
猜你喜欢
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
相关资源
最近更新 更多