我是熊猫的新手,正在尝试基于键联接数据框值。
我的数据框如下:
Slug Position Brand Session Transactions Ecommerce CTR Click
A 0 aaa
A 1 bbb
A 2 ccc
A 3 ddd
B 0 bbb
B 1 ccc
B 2 ddd
B 3 eee
C 0 aaa
C 1 ccc
C 2 ddd
A 70 100 500
A abc fgh
B 60 900 400
B abd fgj
C 50 400 100
C ab fp
我正在尝试使输出如下:
输出:
Slug Position Brand Session Transactions Ecommerce CTR Click
A 0 aaa 70 100 500 abc fgh
A 1 bbb
A 2 ccc
A 3 ddd
B 0 bbb 60 900 400 abd fgj
B 1 ccc
B 2 ddd
B 3 eee
C 0 aaa 50 400 100 ab fp
C 1 ccc
C 2 ddd
数据集:
df = pd.DataFrame({'Slug': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'A', 'A', 'B', 'B', 'C', 'C'],
'Position': ['0', '1', '2', '3', '0', '1', '2', '3', '1', '2', '3', '', '', '', '', '', ''],
'Brand': ['aaa', 'bbb', 'ccc', 'ddd', 'aaa', 'bbb', 'ccc', 'ddd', 'aaa', 'bbb', 'ccc', '', '', '', '', '', ''],
'Session': ['', '', '', '', '', '', '', '', '', '', '', '70', '', '60', '', '50', ''],
'Transaction': ['', '', '', '', '', '', '', '', '', '', '', '80', '', '50', '', '40', ''],
'Ecommerce': ['', '', '', '', '', '', '', '', '', '', '', '700', '', '600', '', '500', ''],
'CTR': ['', '', '', '', '', '', '', '', '', '', '', '', 'abc', '', 'abd', '', 'ffp'],
'Click': ['', '', '', '', '', '', '', '', '', '', '', '', 'ab', '', 'fgh', '', 'fp']})
因此,只需根据匹配的第一个键将值连接起来即可。
我不确定是否应该使用联接或合并,因为数据位于同一数据帧中,而不是两个不同的数据帧中。
我已经尝试过了
df.set_index('Slug').join(df.set_index('Slug'))
但出现此错误:
ValueError: columns overlap but no suffix specified: Index(['Position', 'Brand', 'Sessions', 'Transactions', 'Ecommerce CR', 'CTR',
'All clickouts'],
dtype='object')
我将如何继续努力以取得理想的结果?谢谢您的建议。
答案 0 :(得分:1)
这不是最优雅的方法,但是应该可以起作用:为三个切片创建单独的DF,然后内部合并它们,然后与所需的空行合并。 UPD:抱歉,df_dupl出现错误,已纠正。
df1 = df.dropna(subset=['Position'])
df2 = df.dropna(subset=['Session'])
df3 = df.dropna(subset=['CTR'])
# Keep df1 duplicated all but first in each group.
df_dupl = df[df.duplicated('wind speed', keep=False) & ~df.duplicated('wind speed', keep='first')]
df_res = df1.merge(df2, on=['Slug'], how='inner').merge(df3, on=['Slug'], how='inner')
df_res = pd.concat([df_res, df_dupl]).sort_values(['Slug', 'Position'])
答案 1 :(得分:1)
首先,我们使用GroupBy.bfill
来获取第一行中每个组的值。
然后获取Position
最低的行,并保留这些值并将其他所有设置为NaN
。
最后,通过Position not NaN
上的过滤器删除不需要的行:
df = df.replace('', np.NaN).groupby('Slug').apply(lambda x: x.bfill())
# df['Position'] = pd.to_numeric(df['Position']) --> Use this line if Position column is not numeric
df.loc[:, 'Session':] = (
df.loc[:, 'Session':].where(df['Position'] == df.groupby('Slug')['Position'].transform('min'))
)
df = df[df['Position'].notna()].replace(np.NaN, '')
Slug Position Brand Session Transaction Ecommerce CTR Click
0 A 0.0 aaa 70 80 700 abc fgh
1 A 1.0 bbb
2 A 2.0 ccc
3 A 3.0 ddd
4 B 0.0 aaa 60 50 600 abd fgj
5 B 1.0 bbb
6 B 2.0 ccc
7 B 3.0 ddd
8 C 1.0 aaa 50 40 500 ab fp
9 C 2.0 bbb
10 C 3.0 ccc
说明:
使用.loc
,您可以选择数据帧的一部分以使自己能够替代该部分。在这种情况下,我们选择df.loc[ all rows, all columns from 'Session' and onward]
:
df.loc[:, 'Session':]
Session Transaction Ecommerce CTR Click
0 70 80 700 abc fgh
1 70 80 700 abc fgh
2 70 80 700 abc fgh
3 70 80 700 abc fgh
4 60 50 600 abd fgj
5 60 50 600 abd fgj
6 60 50 600 abd fgj
7 60 50 600 abd fgj
8 50 40 500 ab fp
9 50 40 500 ab fp
10 50 40 500 ab fp
11 70 80 700 abc fgh
12 NaN NaN NaN abc fgh
13 60 50 600 abd fgj
14 NaN NaN NaN abd fgj
15 50 40 500 ab fp
16 NaN NaN NaN ab fp
GroupBy.transform('min')
为我们提供了一个数组,数组的长度与数据帧的长度相同,每行Position
中每组Slug
的最小值:
df.groupby('Slug')['Position'].transform('min')
0 0.0
1 0.0
2 0.0
3 0.0
4 0.0
5 0.0
6 0.0
7 0.0
8 1.0
9 1.0
10 1.0
11 0.0
12 0.0
13 0.0
14 0.0
15 1.0
16 1.0
Name: Position, dtype: float64