在python中通过多个条件合并不同数量的行和列

Posted

技术标签:

【中文标题】在python中通过多个条件合并不同数量的行和列【英文标题】:merging varying number of rows and columns by multiple conditions in python 【发布时间】:2021-06-12 05:00:27 【问题描述】:

更新问题:为什么不合并a_datea_para_consa_menta_le。这些作为没有值的列附加,但在原始数据集中它们具有值。

这是数据集的样子

         connector   type   q_text   a_text   var1   var2 
   1        1111      1      aa       None    xx     ps
   2        9999      2      None     tt      jjjj   pppp
   3        1111      2      None     uu      None   oo
   4        9999      1      bb       None    yy     Rt
   5        9999      1      cc       None    zz     tR

目标:数据集应该的样子

         connector   q_text   a_text    var1   var1.1   var2   var2.1
   1        1111      aa        uu       xx     None     ps      oo
   2        9999      bb        tt       yy     jjjj     Rt      pppp
   3        9999      cc        tt       zz     jjjj     tR      pppp

逻辑:列type 的值为12,其中多行的值为1,但只有一行(connector 中的值相同)具有值2

以下是主要的合并规则:

    type=1 的每一行与其对应的(connector) type=2 行合并。

    由于type=1 的多行具有相同的connector 值,我不想只合并type=1 的一行,而是将它们全部合并,每行都有唯一的type==2 行。

    由于某些列(例如a_text)遵循左连接逻辑,因此可以在不添加额外列的情况下覆盖值。

    由于var2 值不能通过左连接合并,因为它们对于行连接器值是非排他性的,我希望为这些值(@987654347)添加额外的列(var1.1var2.1) @, jjjj)。

总而言之(请记住,我只说具有相同连接器值的行):如果 q_textNone 我首先想将 a_text 中的值替换为 a_text 值(见上表ttuu)对应的行(相同的连接器值),其次,想要附加一些其他值(var1var2)作为新列的非常相同的对应行。 此外,还有不会匹配的具有唯一 connector 值的行。不过我想保留这些行。

我只想“删除”与其对应的type=1 行**(s)** 合并的type=2 行。换句话说:我不想保留 type=2 匹配的行并合并到它们对应的(连接器)type=1 行中。不过,我想保留所有其他行。

@victor__von__doom 的解决方案在这里 merging varying number of rows by multiple conditions in python 当我最初想保留所有 "type"=2 列(值)时得到了回答。

我使用的代码:合并Persoq_texta_text

df.loc[df['type'] == 2, 'a_date'] = df['q_date']
df.loc[df['type'] == 2, 'a_par'] = df['par']
df.loc[df['type'] == 2, 'a_cons'] = df['cons']
df.loc[df['type'] == 2, 'a_ment'] = df['pret']
df.loc[df['type'] == 2, 'a_le'] = df['q_le']
my_cols = ['Perso', 'q_text','a_text', 'a_le', 'q_le', 'q_date', 'par', 'cons', 'pret', 'q_le', 'a_date','a_par', 'a_cons', 'a_ment', 'a_le']
df[my_cols] = df.sort_values(['connector','type']).groupby('connector')[my_cols].transform(lambda x: x.bfill())
df.dropna(subset=['a_text', 'Perso'],inplace=True)
df.reset_index(drop=True,inplace=True)

数据:这是核心数据集的表示。不幸的是,由于隐私法,我无法分享实际数据。

Perso ID per q_le a_le pret par form q_date name IO_ID part area q_text a_text country cons dig connector type
J Ws 1-1/4/2001-11-12/1 1999-2009 None 4325 'Mi, h', 'd' Cew Thre 2001-11-12 None 345 rede s — H None wr ede Terd e e r 2001-11-12.1.g9 999999999 2
S ts 9-3/6/2003-10-14/1 1994-2004 None 23 'sd, h' d-g Thre 2003-10-14 None 34555 The l? I None Tre Thr ede re 2001-04-16.1.a9 333333333 2
On d 6-1/6/2005-09-03/1 1992-2006 None 434 'uu h' d-g Thre 2005-09-03 None 7313 Thde l? I None T e Th rede dre 2001-08-07.1.e4 111111111 2
None 3-4/4/2000-07-07/1 1992-2006 1223 None 'uu h' dfs Thre 2000-07-07 Th r 7413 Thde Tddde Thd de None Thre de 2001-07-06.1.j3 111111111 1
None 2-1/6/2001-11-12/1 1999-2009 1444 None 'Mi, h', 'd' d-g Thre 2001-11-12 T rj 7431 Thde l? I Th dde None Thr ede 2001-11-12.1.s7 999999999 1
None 1-6/4/2007-11-01/1 1993-2010 2353 None None d-g Thre 2007-11-01 Thrj 444 Thed l. I Tgg gg None Thre de we e 2001-06-11.1.g9 654982984 1

【问题讨论】:

如果a_text 的值为type == 1,应该怎么做? 总之,如果q_text是'np.nan'或'none'或字符串'NA',你想用@987654370中的值替换a_text == 1中的值@ == 2?此外,您希望使用来自a_text == 2 的值创建 var1.1 和 var 2.1? 我通过添加更多列来重新运行代码。我的代码没有变化。即使有其他列,它也可以工作。它不会修改这些列的值。您能否分享修改值的行示例? 顺便说一句,要dropna多列,你可以给subset=['q_text', 'person'] 如果您能分享原始数据的链接以便我查看,我将不胜感激。或者提供一组示例行,以便我可以使用它并解决任何问题。目前,我无法看到这些记录被删除的原因。我的编辑 v2 清楚地表明记录保持不变并按要求更新。 【参考方案1】:

使用附加列编辑 v2

此版本可确保其他列中的值不受影响。

c = ['connector','type','q_text','a_text','var1','var2','cumsum','country','others']
d = [[1111, 1, 'aa',  None, 'xx',   'ps',   0, 'US', 'other values'],
     [9999, 2, None,  'tt', 'jjjj', 'pppp', 0, 'UK', 'no values'],
     [1111, 2, None,  'uu', None,   'oo',   1, 'US', 'some values'],
     [9999, 1, 'bb',  None, 'yy',   'Rt',   1, 'UK', 'more values'],
     [9999, 1, 'cc',  None, 'zz',   'tR',   2, 'UK', 'less values']]

import pandas as pd
pd.set_option('display.max_columns', None)
df = pd.DataFrame(d,columns=c)

print (df)

df.loc[df['type'] == 2, 'var1.1'] = df['var1']
df.loc[df['type'] == 2, 'var2.1'] = df['var2']

my_cols = ['q_text','a_text','var1','var2','var1.1','var2.1']

df[my_cols] = df.sort_values(['connector','type']).groupby('connector')[my_cols].transform(lambda x: x.bfill())

df.dropna(subset=['q_text'],inplace=True)
df.reset_index(drop=True,inplace=True)

print (df)

原始数据框:

   connector  type q_text a_text  var1  var2  cumsum country        others
0       1111     1     aa   None    xx    ps       0      US  other values
1       9999     2   None     tt  jjjj  pppp       0      UK     no values
2       1111     2   None     uu  None    oo       1      US   some values
3       9999     1     bb   None    yy    Rt       1      UK   more values
4       9999     1     cc   None    zz    tR       2      UK   less values

更新的数据帧

   connector  type q_text a_text var1 var2  cumsum country        others  var1.1 var2.1
0       1111     1     aa     uu   xx   ps       0      US  other values    None     oo 
1       9999     1     bb     tt   yy   Rt       1      UK   more values    jjjj   pppp 
2       9999     1     cc     tt   zz   tR       2      UK   less values    jjjj   pppp 

【讨论】:

'NA' 是字符串吗?我确实发现了一个问题。如果我们没有2 1111 2 NaN uu NaN,那么来自“2222”的值将更新为1111。现在修复它 您的数据是NA 字符串吗?如果是这样,我需要更改代码。只有当它是NaNNone 时才会起作用 好的。让我更改代码,因为值是字符串'NA' 这解决了您的问题吗?您需要额外的帮助吗?我假设使用 df.loc 分配和 sort_values,你应该很高兴 之前的编辑不需要在答案中 - 只需发布您更新的解决方案。

以上是关于在python中通过多个条件合并不同数量的行和列的主要内容,如果未能解决你的问题,请参考以下文章

根据谷歌电子表格中的行和列条件计算值

根据行和列对矩阵中的所有元素进行排名

Pandas:使用大文件的行和列的条件优化迭代

如何根据pyspark中的行和列条件过滤多行

引导行和列不起作用

在C#中怎样设置table的行和列数,谢谢。