熊猫分组并保持最大长度值

时间:2021-01-02 03:46:15

标签: python pandas

我有以下数据框:

name    state   gender  region  old_ip1 old_ip2 new_ip1 new_ip2
ABC     GA      M       East    1.2.3.4 2.3.4.5     
ABC     GA      M       East                
ABC     GA      M       East                
ABC     GA      M       East                    3.4.5.6 4.5.6.7
ABC     A       M       South               
ABC     GA      M       South   5.6.7.8 6.7.8.9     
ABC     GA      M       South                   7.8.9.1 8.9.1.2
BCD     GA      M       East    9.1.2.3 1.2.3.4     
BCD     GA      M       East                    2.3.4.5 3.4.5.6

我需要按前 4 列按数据框分组,并保留 ip 值。每个组有一行是旧 ip 1 和 2,另一行是新 ip 1 和 2。一个组也可能包含旧 ip 和新 ip 中没有任何值的行。

输出应该是:

name    state   gender  region  old_ip1 old_ip2 new_ip1 new_ip2
ABC     GA      M       East    1.2.3.4 2.3.4.5 3.4.5.6 4.5.6.7 
ABC     GA      M       South   5.6.7.8 6.7.8.9 7.8.9.1 8.9.1.2
BCD     GA      M       East    9.1.2.3 1.2.3.4 2.3.4.5 3.4.5.6

我想连接每个组的所有值,或使用最大值,但都不起作用。到目前为止,这是我的代码:

df.groupby(['name', 'state', 'gender', 'region'], as_index=False).agg(lambda x : ';'.join(x))
df.groupby(['name', 'state', 'gender', 'region'], as_index=False).max()

错误信息:

raise ValueError(
ValueError: Wrong number of items passed 1, placement implies 6

正在寻找解决方案。它不一定要串联。

2 个答案:

答案 0 :(得分:0)

你可以pd.merge

首先设置索引并用 NaN 替换空值。

df = df.set_index(['name', 'state', 'gender', 'region'])
df = df.replace('', np.nan) 

然后你可以像这样合并,删除空值:

df_old = df[['old_ip1', 'old_ip2']].dropna()
df_new = df[['new_ip1', 'new_ip2']].dropna()

df = pd.merge(df_old, df_new, left_index=True, right_index=True)

输出

                          old_ip1  old_ip2  new_ip1  new_ip2
name state gender region
ABC  GA    M      East    1.2.3.4  2.3.4.5  3.4.5.6  4.5.6.7
                  South   5.6.7.8  6.7.8.9  7.8.9.1  8.9.1.2
BCD  GA    M      East    9.1.2.3  1.2.3.4  2.3.4.5  3.4.5.6

答案 1 :(得分:0)

您可以使用 max。您只需要确保所有数据都包含字符串,因此我使用 .fillna('0'):

df = df.replace('', np.nan).fillna('0')
df = df.groupby(['name', 'state', 'gender', 'region'], as_index=False).max()
df
Out[1]: 
  name state gender region  old_ip1  old_ip2  new_ip1  new_ip2
0  ABC    GA      M   East  1.2.3.4  2.3.4.5  3.4.5.6  4.5.6.7
1  ABC    GA      M  South  5.6.7.8  6.7.8.9  7.8.9.1  8.9.1.2
2  BCD    GA      M   East  9.1.2.3  1.2.3.4  2.3.4.5  3.4.5.6

或者,您可以将 groupbyfill()bfill() 一起使用,然后使用 drop_duplicates()

df = df.replace('', np.nan) 
cols= ['old_ip1', 'old_ip2', 'new_ip1', 'new_ip2']
df[cols] = df.groupby(['name', 'state', 'gender', 'region']).ffill().bfill()
df = df.drop_duplicates()
df
Out[1]: 
  name state gender region  old_ip1  old_ip2  new_ip1  new_ip2
0  ABC    GA      M   East  1.2.3.4  2.3.4.5  3.4.5.6  4.5.6.7
4  ABC    GA      M  South  5.6.7.8  6.7.8.9  7.8.9.1  8.9.1.2
7  BCD    GA      M   East  9.1.2.3  1.2.3.4  2.3.4.5  3.4.5.6