簡體   English   中英

基於出現合並行,同時在 Python 中的 DataFrame 中保持唯一值

[英]Coalescing the Rows based on occurence and while maintaining unique values in a DataFrame in Python

數據框:

Name         Category        Port          Class
A                Code         443        string1
A                Code          80        string2
B                Math         443        string3
A                Code         443        string1
B                Math          80        string4

我嘗試過的代碼:

df1 = df.name.ne(df.name.shift())
count = df.name.groupby(df1.cumsum()).size()

我得到的輸出:

Name     Category      Port       Class     Count
A            Code       443     string1         2
B            Math       443     string3         1
A            Code       443     string1         1
B            Math        80     string4         1

我想要的輸出:

Name    Category         Port               Class   Count
A           Code      443, 80    string1, string2       2
B           Math          443             string3       1
A           Code          443             string1       1
B           Math           80             string4       1

任何幫助表示贊賞。

使用具有適當功能的groupbyagg應該groupby您的需求。 下面使用的list將導致所有值都被保留,如果您只想要唯一的值,您可以將其更改為set

df['cumsum'] = df.Name.ne(df.Name.shift()).cumsum()
df2 = df.groupby(df["cumsum"]).agg({'Name': 'first', 'Category': 'first', 'Port': list, 'Class': [list, 'count']})
df2.columns = df2.columns.droplevel(1).values[:-1].tolist() + ['Count']
df2 = df2.reset_index(drop=True)

這會給你:

  Name  Category       Port               Class  Count
0    A      Code  [443, 80]  [string1, string2]      2
1    B      Math      [443]           [string3]      1
2    A      Code      [443]           [string1]      1
3    B      Math       [80]           [string4]      1

這里的關鍵是識別具有通用名稱和類別的連續行。 一個簡單的技巧是使用shiftcumsum

x = pd.Series(np.where((df['Name'] == df1['Name'])&(df['Category'] == df1['Category']), 0, 1),
              index = df.index).cumsum()

一旦完成,一個groupbyagg就完成了這項工作:

df.assign(Count=1, Port=df['Port'].astype(str)).groupby(['Name', 'Category',x]).agg(
    {'Port': ', '.join, 'Class': ', '.join, 'Count': 'sum'}).reset_index().drop(columns='level_2')

它給:

  Name Category     Port             Class  Count
0    A     Code  443, 80  string1, string2      2
1    A     Code      443           string1      1
2    B     Math      443           string3      1
3    B     Math       80           string4      1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM