在python中通过多个条件合并不同数量的行和列
Posted
技术标签:
【中文标题】在python中通过多个条件合并不同数量的行和列【英文标题】:merging varying number of rows and columns by multiple conditions in python 【发布时间】:2021-06-12 05:00:27 【问题描述】:更新问题:为什么不合并a_date
、a_par
、a_cons
、a_ment
和a_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
的值为1
或2
,其中多行的值为1
,但只有一行(connector
中的值相同)具有值2
以下是主要的合并规则:
将type=1
的每一行与其对应的(connector
) type=2
行合并。
由于type=1
的多行具有相同的connector
值,我不想只合并type=1
的一行,而是将它们全部合并,每行都有唯一的type==2
行。
由于某些列(例如a_text
)遵循左连接逻辑,因此可以在不添加额外列的情况下覆盖值。
由于var2
值不能通过左连接合并,因为它们对于行连接器值是非排他性的,我希望为这些值(@987654347)添加额外的列(var1.1
、var2.1
) @, jjjj
)。
总而言之(请记住,我只说具有相同连接器值的行):如果 q_text
是 None
我首先想将 a_text
中的值替换为 a_text
值(见上表tt
和uu
)对应的行(相同的连接器值),其次,想要附加一些其他值(var1
和var2
)作为新列的非常相同的对应行。
此外,还有不会匹配的具有唯一 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
列(值)时得到了回答。
我使用的代码:合并Perso
、q_text
和a_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
字符串吗?如果是这样,我需要更改代码。只有当它是NaN
或None
时才会起作用
好的。让我更改代码,因为值是字符串'NA'
这解决了您的问题吗?您需要额外的帮助吗?我假设使用 df.loc 分配和 sort_values,你应该很高兴
之前的编辑不需要在答案中 - 只需发布您更新的解决方案。以上是关于在python中通过多个条件合并不同数量的行和列的主要内容,如果未能解决你的问题,请参考以下文章