Python 在关键帧上连接数据帧值

Python 在关键帧上连接数据帧值,python,pandas,dataframe,Python,Pandas,Dataframe,我不熟悉pandas,并且尝试基于键连接数据帧值 我的数据框如下所示: 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

我不熟悉pandas,并且尝试基于键连接数据帧值

我的数据框如下所示:

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']})
因此,只需根据匹配的第一个键连接这些值

我不确定是否应该使用join或merge,因为数据位于同一数据帧中,而不是两个不同的数据帧中

我试过这个

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')

我将如何继续努力获得我想要的结果?谢谢您的建议。

这不是最优雅的方式,但应该可以:为三个切片创建单独的DFs,然后内部合并它们,然后使用所需的空行进行合并。 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'])

首先,我们使用
GroupBy.bfill
获取第一行中每个组的值

然后获取位置最低的
,保留这些值,并将其他所有值设置为
NaN

最后,我们在
位置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, '')

说明

使用
.loc
可以选择数据帧的一个片段,以使自己能够替换该片段。在这种情况下,我们选择
df.loc[所有行,所有列,从'Session'开始]

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')
为我们返回一个与数据帧长度相同的数组,并在每行上为每组
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

由于所有的空格,您的数据很难复制和用于创建答案。最好的方法是通过
pd.DataFrame(..)
包含您的数据,这样我们就可以复制并运行代码。嗨@Erfan,我已经添加了DataFrame,希望它能有所帮助。做得好,投票结果令人满意。顺便说一句,它还不完全正确,请查看列
CTR
click
,这些值是错误的。你能编辑吗?@Erfan,在问题中修复了它,谢谢你发现了它。有一些高级熊猫,会研究它的。你能解释一下
df.loc[:,'Session':]
选择了什么吗?
.transform(min)
有什么作用?我注意到,如果我按任何列降序或升序对新的数据框进行排序,它将无法正常工作,您知道为什么吗?请参见编辑并给出解释。回答您关于排序的问题。这是因为我们使用
bfill
并在每个组中只保留最低
位置的值(原因是我们使用
Groupby.transform(min)
。因此,如果排序时最低位置不在每个组的第一行,此方法将不起作用。任何解决方法我都可以通过某种方式使排序重新开始工作?“排序”是相当广泛的,你必须更具体(按哪列排序,升序还是降序?)。此外,我无法继续编辑此答案,因此将您的原始问题视为已回答。请随意打开其他问题,我将很乐意帮助您。
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