我有一个像这样的数据集
Day1 Day2 Day3 Day4 ID Product Price
Day2 Day4 2 X 50
Day1 Day3 Day4 3 Y 60
Day2 Day3 4 Z 70我想以这种方式聚合它
Days ID Product Price
Day2&Day4 2 X 50
Day1&Day3&Day4 3 Y 60
Day2&Day3 4 Z 70我发现很难理清背后的逻辑。
原始输入:
df = pd.DataFrame({'Day1': ['', 'Day1', ''],
'Day2': ['Day2', '', 'Day2'],
'Day3': ['', 'Day3', 'Day3'],
'Day4': ['Day4', 'Day4', ''],
'ID': [2, 3, 4],
'Product': ['X', 'Y', 'Z'],
'Price': [50, 60, 70]})发布于 2022-01-06 12:30:41
您可以将相关列转换为列表列表,并使用列表理解,在每次迭代中,您可以过滤空空间,并在中间使用&连接其余的项。然后将此字符串列表分配给'Days'列。最后,删除多余的列并按首选的顺序重新排列其余的列。
cols = ['Day1', 'Day2', 'Day3', 'Day4']
df['Days'] = ['&'.join(x for x in lst if x!='') for lst in df[cols].to_numpy().tolist()]
df = df.drop(cols, axis=1)[['Days','ID','Product','Price']]输出:
Days ID Product Price
0 Day2&Day4 2 X 50
1 Day1&Day3&Day4 3 Y 60
2 Day2&Day3 4 Z 70发布于 2022-01-06 12:35:32
我有全自动版本。更多的代码行,但有效。我发现所有以"Day“短语开头的列,然后将它们连接起来,然后删除旧列并重新排序列。
cols = df.columns[pd.Series(df.columns).str.startswith('Day')]
df['Days'] = df[cols].apply('&'.join, axis=1).str.strip('&')
df.drop(columns = cols, inplace = True)
col = df.pop("Days")
df.insert(0, col.name, col)
# To clear double '&' chars.
import re
df['Days'] = [re.sub('&+', '&', day) for day in df['Days']]发布于 2022-01-06 12:38:03
注意:假设你的空单元格是'NaN',如果不是,你可以使用df.replace({'': float('nan')})作为第一步
你可以stack和groupby+apply('&'.join)
df['Days'] = df.filter(like='Day').stack().groupby(level=0).apply('&'.join)堆叠操作可以清除空单元格。
产出:
Day1 Day2 Day3 Day4 ID Product Price Days
0 NaN Day2 NaN Day4 2 X 50 Day2&Day4
1 Day1 NaN Day3 Day4 3 Y 6 Day1&Day3&Day4
2 NaN Day2 Day3 NaN 4 Z 70 Day2&Day3删除原始DaysX列:
cols = list(df.filter(like='Day').columns)
df['Days'] = df[cols].stack().groupby(level=0).apply('&'.join)
df.drop(columns=cols)产出:
ID Product Price Days
0 2 X 50 Day2&Day4
1 3 Y 6 Day1&Day3&Day4
2 4 Z 70 Day2&Day3https://stackoverflow.com/questions/70606842
复制相似问题