使用 pandas 爆炸后获取 groupby 的下一个值
Getting next value of groupby after explode with pandas
我试图在 Emails
列的每一行内获取列表的第一个非空值以写入 Email_final1
然后在每一行内获取列表的下一个值Emails
,如果有一个,到Emails_final2
,否则将Emails2
值写入Emails2_final
,如果不为空且不等于'Emails',否则离开Emails_final2
空白。最后,如果 Emails 2
中的值被写入 Emails_final1
,则使 Emails_final2
None
我尝试了很多不同的方法来实现这一点,但都无济于事,这是我目前所拥有的,包括伪代码:
我当前的代码:
df = pd.DataFrame({'Emails': [['jjj@gmail.com', 'jp@gmail.com', 'jc@gmail.com'],[None, 'www@gmail.com'],[None,None,None]],
'Emails 2': ['sss@gmail.com', 'zzz@gmail.com','ccc@gmail.com'],
'num_specimen_seen': [10, 2,3]},
index=['falcon', 'dog','cat'])
df['Emails_final1'] = df['Emails'].explode().groupby(level=0).first()
#pseudo code
df['Emails_final2'] = df['Emails'].explode().groupby(level=0).next() #I know next doesn't exist but I want it to try to get the next value of 'Emails' before trying to get 'Emails 2 values.
期望的输出:
Emails_final1 Emails_final2
falcon jjj@gmail.com jp@gmail.com
falcon www@gmail.com zzz@gmail.com
falcon ccc@gmail.com None
任何有关如何解决此类问题的指导都将不胜感激。
它看起来有点乱,但它确实有效。基本上,我们在填充“Emails_final1”的第一步中保留了一个布尔掩码,并在第二步中使用它来填充“Emails_final1”。
要填充第二列,想法是使用 groupby
+ nth
来获取第二个元素,如果它们与之前 selected 的电子邮件不匹配;保留它(例如第一行),但如果它不是来自“电子邮件 2”列的 select,除非它之前已经 selected(例如在第三行):
exp_g = df['Emails'].explode().groupby(level=0)
df['Emails_final1'] = exp_g.first()
msk = df['Emails_final1'].notna()
df['Emails_final1'] = df['Emails_final1'].fillna(df['Emails 2'])
df['Emails_final2'] = exp_g.nth(1)
df['Emails_final2'] = df['Emails_final2'].mask(lambda x: ((x == df['Emails_final1']) | x.isna()) & msk, df['Emails 2'])
相关栏目是:
Emails_final1 Emails_final2
falcon jjj@gmail.com jp@gmail.com
dog www@gmail.com zzz@gmail.com
cat ccc@gmail.com None
我试图在 Emails
列的每一行内获取列表的第一个非空值以写入 Email_final1
然后在每一行内获取列表的下一个值Emails
,如果有一个,到Emails_final2
,否则将Emails2
值写入Emails2_final
,如果不为空且不等于'Emails',否则离开Emails_final2
空白。最后,如果 Emails 2
中的值被写入 Emails_final1
,则使 Emails_final2
None
我尝试了很多不同的方法来实现这一点,但都无济于事,这是我目前所拥有的,包括伪代码:
我当前的代码:
df = pd.DataFrame({'Emails': [['jjj@gmail.com', 'jp@gmail.com', 'jc@gmail.com'],[None, 'www@gmail.com'],[None,None,None]],
'Emails 2': ['sss@gmail.com', 'zzz@gmail.com','ccc@gmail.com'],
'num_specimen_seen': [10, 2,3]},
index=['falcon', 'dog','cat'])
df['Emails_final1'] = df['Emails'].explode().groupby(level=0).first()
#pseudo code
df['Emails_final2'] = df['Emails'].explode().groupby(level=0).next() #I know next doesn't exist but I want it to try to get the next value of 'Emails' before trying to get 'Emails 2 values.
期望的输出:
Emails_final1 Emails_final2
falcon jjj@gmail.com jp@gmail.com
falcon www@gmail.com zzz@gmail.com
falcon ccc@gmail.com None
任何有关如何解决此类问题的指导都将不胜感激。
它看起来有点乱,但它确实有效。基本上,我们在填充“Emails_final1”的第一步中保留了一个布尔掩码,并在第二步中使用它来填充“Emails_final1”。
要填充第二列,想法是使用 groupby
+ nth
来获取第二个元素,如果它们与之前 selected 的电子邮件不匹配;保留它(例如第一行),但如果它不是来自“电子邮件 2”列的 select,除非它之前已经 selected(例如在第三行):
exp_g = df['Emails'].explode().groupby(level=0)
df['Emails_final1'] = exp_g.first()
msk = df['Emails_final1'].notna()
df['Emails_final1'] = df['Emails_final1'].fillna(df['Emails 2'])
df['Emails_final2'] = exp_g.nth(1)
df['Emails_final2'] = df['Emails_final2'].mask(lambda x: ((x == df['Emails_final1']) | x.isna()) & msk, df['Emails 2'])
相关栏目是:
Emails_final1 Emails_final2
falcon jjj@gmail.com jp@gmail.com
dog www@gmail.com zzz@gmail.com
cat ccc@gmail.com None