【问题标题】:Pandas Mapping 2 dfs熊猫映射 2 dfs
【发布时间】:2018-06-05 08:49:19
【问题描述】:

我想执行从 df 中的 2 个字段到另一个 df1 的 1 个字段的映射。但是,df1 的字段名称为空。
df:

Name1  Name2 Value
x      x-y      1
x      x-z      2
y      y-z      3
y      y-x      5
z      z-y      7

df1:(可以给这个空槽起个名字吗?)

      Num     
x     1
y     2
z     3
a     4
a-b   5
x-y   0
x-z   5
y-z   0
y-x   5
z-y   0

输出将是:

Name1  Name2 Value  Num1   Num2
x      x-y      1     1     0
x      x-z      2     1     5
y      y-z      3     2     0
y      y-x      5     2     5
z      z-y      7     3     0

谢谢你,节日快乐!

【问题讨论】:

    标签: python pandas dataframe mapping


    【解决方案1】:

    我选择map,你也可以试试mergejoin,试试看索引,merge里面应该是df1.merge(df2,left_on='Name1',right_index=True)

    df['Num1']=df.Name1.map(df1.Num)
    df['Num2']=df.Name2.map(df1.Num)
    df
    Out[1150]: 
      Name1 Name2  Value  Num1  Num2
    0     x   x-y      1     1     0
    1     x   x-z      2     1     5
    2     y   y-z      3     2     0
    3     y   y-x      5     2     5
    4     z   z-y      7     3     0
    

    另一种方式

    df=df.set_index('Value').stack()
    df.map(df1.Num)
    
    pd.concat([df,df.map(df1.Num)],1).unstack()
    Out[1169]: 
              0           1      
          Name1 Name2 Name1 Name2
    Value                        
    1         x   x-y     1     0
    2         x   x-z     1     5
    3         y   y-z     2     0
    5         y   y-x     2     5
    7         z   z-y     3     0
    

    【讨论】:

    • @Evan Wen 比我快,所以我至少可以帮助重命名部分。这是怎么做的:首先重置索引(未命名的列实际上不是列而是索引) df1 = df1.reset_index() 然后重命名: df1.rename(columns={'index':'Name3'} , 就地=真)
    • @Evan 是索引,而不是列。如果需要,可以通过 df1.index.rename('Some you want') 重命名索引,将其转换为列 df1.reset_index()
    • @TylerNG 是的,您可以将索引命名为:df.index.name = ...,或使用df.rename_axis
    • @TylerNG 或者这样:首先重置索引(未命名的列实际上不是列而是索引) df1 = df1.reset_index() 然后重命名: df1.rename(columns={' index':'Name3'}, inplace=True)
    • 你们让编码看起来很容易 :) 谢谢大家。节日快乐!
    【解决方案2】:

    选项 1
    你可以使用loc + values -

    df.assign(
        Num1=df2.loc[df.Name1].values, Num2=df2.loc[df.Name2].values
    )
    
      Name1 Name2  Value  Num1  Num2
    0     x   x-y      1     1     0
    1     x   x-z      2     1     5
    2     y   y-z      3     2     0
    3     y   y-x      5     2     5
    4     z   z-y      7     3     0
    

    选项 2
    loc + concat 的另一个有趣的选择 -

    i = df2.loc[df.values[:, :2].ravel()].values
    j = pd.DataFrame(i.reshape(len(df), -1), columns=['Num1', 'Num2'])
    
    pd.concat([df, j], 1)
    
    
      Name1 Name2  Value  Num1  Num2
    0     x   x-y      1     1     0
    1     x   x-z      2     1     5
    2     y   y-z      3     2     0
    3     y   y-x      5     2     5
    4     z   z-y      7     3     0
    

    【讨论】:

    • 节日快乐 :-)
    【解决方案3】:

    将其移出 cmets 只是为了可见性:

          Num     
    x     1
    y     2
    z     3
    a     4
    a-b   5
    x-y   0
    x-z   5
    y-z   0
    y-x   5
    z-y   0
    
    df1 = pd.read_clipboard()
    

    输出:

         Num
    x      1
    y      2
    z      3
    a      4
    a-b    5
    x-y    0
    x-z    5
    y-z    0
    y-x    5
    z-y    0
    

    字母列是索引。要重命名它,您必须使用 @cᴏʟᴅsᴘᴇᴇᴅ的解决方案:

    df.index.name = 'name'

    如果您尝试像重命名列一样重命名索引,它将不起作用(有或没有inplace = True):

    df1.rename(columns = {'': 'Name'}, inplace = True)
    print(df1)
    

    返回:

         Num
    x      1
    y      2
    z      3
    a      4
    a-b    5
    x-y    0
    x-z    5
    y-z    0
    y-x    5
    z-y    0
    

    感谢讨论。

    pandas rename index values

    【讨论】:

      【解决方案4】:

      已经给出了完美的答案,但我只是有一个注释。如果您没有重命名未命名的列(称为索引),则发布的解决方案将完美运行。我将展示如何进行重命名,并回答如何在重命名后进行连接。

      import pandas as pd
      import sys
      if sys.version_info[0] < 3:
          from StringIO import StringIO
      else:
          from io import StringIO
      
      # Create df
      rawText = StringIO("""
      Name1  Name2 Value
      x      x-y      1
      x      x-z      2
      y      y-z      3
      y      y-x      5
      z      z-y      7
      """)
      df = pd.read_csv(rawText, sep = "\s+")
      
      #Create df1 by renaming the unnamed index as Name3
      rawText = StringIO("""
            Num     
      x     1
      y     2
      z     3
      a     4
      a-b   5
      x-y   0
      x-z   5
      y-z   0
      y-x   5
      z-y   0
      """)
      df1 = pd.read_csv(rawText, sep = "\s+")
      df1 = df1.reset_index() # This works when you have multiple unnamed indices too
      df1.rename(columns={'index':'Name3'}, inplace=True)
      
      # Here is the solution
      df.merge(df1, left_on='Name1', right_on='Name3')
      

      非常有成果的讨论,节日快乐!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-12
        • 2019-01-02
        • 2018-05-14
        • 2019-07-30
        • 1970-01-01
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多