旋转数据框以将特定行转换为基于某一特定列的列

时间:2020-01-03 13:01:15

标签: python python-3.x pandas dataframe dns

我有一个包含如下记录的dns数据集:-

Query_Type    Query_name    Response_ttl    ip4_address  NS_Name         MX_Name
  A             google.com      400            1.1.1.1     null                  null
  A             google.com      600            2.2.2.2     null                  null
  NS            google.com      500            3.3.3.3     ns1.google.com        null
  MX             google.com     400            null        null                  gmail.com
  A             facebook.com    400            4.4.4.4     null                  null
  NS            facebook.com    500            5.5.5.5     ns1.facebook.com      null
  .
  .

我希望期望的输出表将基于Query_name和所有其他列的所有记录合并为如下行:-

**Query_name  Query_type_A_ip   Query_type_A_ttl Query_type_NS_Name Query_type_NS_ttl ...**
 google.com    1.1.1.1,2.2.2.2   avg(400+600)      ns1.google.com        400
 facebook.com   4.4.4.4          avrg(ttls of A)  ....

我知道pandas库具有 pivot 功能来执行此操作。但是只是不知道该怎么做。请帮忙

1 个答案:

答案 0 :(得分:3)

我认为您首先需要DataFrame.melt,通过DataFrame.dropna删除丢失的行,并通过DataFrame.pivot_table进行整形,最后通过MultiIndexmap展平:

df = (df.melt(['Query_Type','Query_name','Response_ttl'], value_name='ip')
        .dropna(subset=['ip'])
        .pivot_table(index='Query_name', 
                     columns=['Query_Type', 'variable'], 
                     aggfunc={'Response_ttl':'mean','ip': lambda x: ', '.join(x.astype(str))})
        .sort_index(axis=1, level=[1,2]))
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}_{x[2]}')
df = df.reset_index()
print (df)
     Query_name  Response_ttl_A_ip4_address  ip_A_ip4_address  \
0  facebook.com                       400.0           4.4.4.4   
1    google.com                       500.0  1.1.1.1, 2.2.2.2   

   Response_ttl_MX_MX_Address ip_MX_MX_Address  Response_ttl_NS_NS_Address  \
0                         NaN              NaN                       500.0   
1                       400.0        gmail.com                       500.0   

   ip_NS_NS_Address  Response_ttl_NS_ip4_address ip_NS_ip4_address  
0  ns1.facebook.com                        500.0           5.5.5.5  
1    ns1.google.com                        500.0           3.3.3.3  

或者如果地址列的值不重要,请忽略它们:

df1 = (df.melt(['Query_Type','Query_name','Response_ttl'], value_name='ip')
         .dropna(subset=['ip'])
         .pivot_table(index='Query_name', 
                      columns='Query_Type', 
                      aggfunc={'Response_ttl':'mean','ip': lambda x: ', '.join(x.astype(str))})
         .sort_index(axis=1, level=1))
df1.columns = df1.columns.map(lambda x: f'{x[0]}_{x[1]}')
df1 = df1.reset_index()
print (df1)
     Query_name  Response_ttl_A              ip_A  Response_ttl_MX      ip_MX  \
0  facebook.com           400.0           4.4.4.4              NaN        NaN   
1    google.com           500.0  1.1.1.1, 2.2.2.2            400.0  gmail.com   

   Response_ttl_NS                      ip_NS  
0            500.0  5.5.5.5, ns1.facebook.com  
1            500.0    3.3.3.3, ns1.google.com