【问题标题】:Joining pandas dataframe values on key在键上加入熊猫数据框值
【发布时间】:2019-12-12 18:09:26
【问题描述】:

我是 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']})

所以只需根据匹配的第一个键加入值。

我不确定是否应该使用联接或合并,因为数据在同一个数据框中,而不是两个不同的数据框中。

我试过了

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

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

【问题讨论】:

  • 由于所有的空格,您的数据真的很难复制和用于创建答案。最好的方法是通过pd.DataFrame(..) 包含您的数据,以便我们可以复制并运行代码。
  • 嗨@Erfan,我已经添加了数据框,希望对您有所帮助。
  • 干得好,为努力点赞
  • 顺便说一句,这还不完全正确,请查看CTRclick 列,那里的值是错误的。可以编辑吗?
  • @Erfan,在问题中修复了它,感谢您发现它。

标签: python pandas dataframe


【解决方案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') 为我们返回一个与我们的数据帧长度相同的数组,并且在每一行上,每组 Slug 的最小值为 Position

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

【讨论】:

  • 有一些高级的熊猫,会研究一下。你能解释一下df.loc[:,'Session':] 选择了什么吗? .transform(min) 是做什么的?
  • 我注意到,如果我按任何列降序或升序对新数据帧进行排序,它就不能正常工作,你知道为什么吗?
  • 查看编辑说明。回答你关于排序的问题。这是因为我们使用bfill 并且只保留每组最低Position 的值(因为我们使用Groupby.transform(min)。所以如果你排序并且最低位置不在每组的第一行,这种方法将不起作用.
  • 有什么解决方法可以让排序重新开始工作吗?
  • “排序”很宽泛,你必须更具体(按哪一列排序,升序还是降序?)。另外,我无法继续编辑此答案,因此将您的原始问题视为已回答。如有其他问题,请随时提出另一个问题,我很乐意为您提供帮助。
【解决方案2】:

不是最优雅的方式,但应该可行:为三个切片创建单独的 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'])

【讨论】:

    猜你喜欢
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多