I want to create 03 new columns in a dataframe
Create a new column in the dataframe of unique values of
cfop_code
for eachkey
A column that check the number of unique values that shows in unique_list
A column that check the number of not unique values that shows in unique_list
key | product | cfop_code | |
---|---|---|---|
0 | 12345678901234567890 | product a | 2551 |
1 | 12345678901234567890 | product b | 2551 |
2 | 12345678901234567890 | product c | 3551 |
3 | 12345678901234567895 | product a | 2551 |
4 | 12345678901234567897 | product b | 2551 |
5 | 12345678901234567897 | product c | 2407 |
key | product | cfop_code | unique_list | unique_count | not_unique_count | |
---|---|---|---|---|---|---|
0 | 12345678901234567890 | product a | 2551 | 2251, 3551 | 2 | 3 |
1 | 12345678901234567890 | product b | 2551 | 2251, 3551 | 2 | 3 |
2 | 12345678901234567890 | product c | 3551 | 2251, 3551 | 2 | 3 |
3 | 12345678901234567895 | product a | 2551 | 2251 | 1 | 1 |
4 | 12345678901234567897 | product b | 2551 | 2407, 2551 | 2 | 2 |
5 | 12345678901234567897 | product c | 2407 | 2407, 2551 | 2 | 2 |
df.groupby('key')["cfop"].unique()
key
12345678901234567890 [2551, 3551]
12345678901234567895 [2551]
12345678901234567897 [2551, 2407]
Name: cfop, dtype: object
df.groupby("key").agg(**{"unique_values": pd.NamedAgg(column='cfop', aggfunc="size")}).reset_index()
key unique_values
0 12345678901234567890 3
1 12345678901234567895 1
2 12345678901234567897 2
df.groupby("key").agg(**{"unique_values": pd.NamedAgg(column='cfop', aggfunc="nunique")}).reset_index()
key unique_values
0 12345678901234567890 2
1 12345678901234567895 1
2 12345678901234567897 2
df['unique_list'] = df.groupby('key')["cfop"].unique()
df['unique_count'] = df.groupby("key").agg(**{"unique_values": pd.NamedAgg(column='cfop', aggfunc="nunique")}).reset_index()
df['not_unique_count'] =df.groupby("key").agg(**{"unique_values": pd.NamedAgg(column='cfop', aggfunc="size")}).reset_index()
Try:
tmp = (
df.groupby("key")["cfop_code"]
.agg(
unique_list = lambda s: sorted(s.unique()),
unique_count = "nunique",
not_unique_count = "size")
.reset_index()
)
res = df.merge(tmp, on="key")
print(res)
key product cfop_code unique_list unique_count not_unique_count
0 12345678901234567890 product a 2551 [2551, 3551] 2 3
1 12345678901234567890 product b 2551 [2551, 3551] 2 3
2 12345678901234567890 product c 3551 [2551, 3551] 2 3
3 12345678901234567895 product a 2551 [2551] 1 1
4 12345678901234567897 product b 2551 [2407, 2551] 2 2
5 12345678901234567897 product c 2407 [2407, 2551] 2 2
The problem with your attempt is that:
df.groupby("key").agg(**{"unique_values": pd.NamedAgg(column='cfop_code', aggfunc="nunique")}).reset_index()
returns a DataFrame.You try to assign this whole DataFrame to a new column which fails.