使用Pivot_Table时如何克服错误的合并?

时间:2019-03-22 23:16:10

标签: python-3.x pandas dataframe pivot-table multiple-columns

我有两个数据框,我想做的是基于Sensor_Type创建新列,并将它们添加到DF1,然后根据Sensor分配每个测量值。

DF1:

  Weather_Legends.head():

  Sensor_ID Sensor_Street_Name  Sensor_Lat  Sensor_Long   Sensor_Type         UOM
 0  6030    Milano - via Brera  45.471192   9.187616    Wind Direction      degree
 1  5897    Milano - via Brera  45.471192   9.187616      Temperature   Celsius degree
 2  6174    Milano - via Brera  45.471192   9.187616    Relative Humidity      %
 3  6120    Milano - via Brera  45.471192   9.187616      Wind Speed         m/s
 4  2006    Milano - via Lambrate  45.490051  9.22559   Precipitation        mm

DF2:

  Mi_Meteo.head():

  Sensor_ID    Time_Instant     Measurement
0   14121   2013-11-01 01:00:00   0.8
1   14121   2013-11-01 02:00:00   0.6
2   14121   2013-11-01 03:00:00   0.4
3   14121   2013-11-01 04:00:00   0.4
4   14121   2013-11-01 05:00:00    0

这是所需的输出:

Sensor_Type Sensor_ID   Sensor_Street_Name             Time_Instant      Precipitation     Relative Humidity    Wind Speed  …..
     0      14121     Milano - via Ippolito Rosellini   2013-11-01 01:00:00   0.8              NaN              NaN
     1      14121     Milano - via Ippolito Rosellin    2013-11-01 02:00:00   NaN              0.6              NaN
     2      14121     Milano - via Ippolito Rosellini   2013-11-01 03:00:00   0.4               NaN             NaN
     .
     .
     .

相反,这些就是我得到的:

 Sensor_Type Sensor_ID  Sensor_Street_Name               Time_Instant     Precipitation
   0          14121    Milano - via Ippolito Rosellini   2013-11-01 01:00:00    0.8
   1          14121    Milano - via Ippolito Rosellini   2013-11-01 02:00:00    0.6
   2          14121    Milano - via Ippolito Rosellini   2013-11-01 03:00:00    0.4
   .
   .

其他传感器类型丢失!!!

这是我使用的代码:

    Mi_Meteo['Measurement'] = Mi_Meteo['Measurement'].str.rstrip(' Measure').str.strip()
    Mi_Meteo['Measurement'] = pd.to_numeric(Mi_Meteo['Measurement'] ,errors='coerce' )
    Mi_Meteo['Sensor_ID'] = Mi_Meteo['Sensor_ID'].str.rstrip(' ID').str.strip()
    Mi_Meteo['Sensor_ID'] = pd.to_numeric(Mi_Meteo['Sensor_ID'] ,errors='coerce' )

    Mi_Meteo['Measurement'] = Mi_Meteo['Measurement'].astype(float)
    Mi_Meteo['Sensor_ID'] = Mi_Meteo['Sensor_ID'].astype(float)

    df4 = Mi_Meteo.merge(Weather_Legends, on='Sensor_ID', how='left')\
                  .pivot_table(index=['Sensor_ID' ,'Sensor_Street_Name' , 'Time_Instant' ], 
                               values= 'Measurement', 
                               columns='Sensor_Type')\
                  .reset_index()
    df4['Sensor_ID'] = df4['Sensor_ID'].astype(int)

任何建议都会受到赞赏,谢谢大家。

1 个答案:

答案 0 :(得分:2)

在没有您的数据的情况下,我用一些随机数据组成了这些数据,这些数据反映了我所了解的您的结构。

下面的代码有效,并且为您提供了我认为您正在寻找的东西。这类似于您似乎所做的事情,因此我只能猜测您的数据结构中肯定有一些错误。

这听起来真的很平庸,但是您是否已验证其他传感器的读数(风等)呢?根据输出,似乎只有降水量读数。

您的“所需输出”没有意义,因为它表明相同的传感器ID记录了雨水和湿度。但是您说每个传感器ID仅与一种传感器类型相关联!

例如应用了公式后,“传感器ID”可能不是主键吗?在https://www.essentialsql.com/what-is-the-difference-between-a-primary-key-and-a-foreign-key/或在线提供的数万亿资源中查找这些概念。检查数据的结构。

听起来并不是破纪录,而是:主键和外键!您确实非常需要了解数据的结构。

如果在仔细研究了这些概念并查看了数据之后,仍然看不到问题所在,可以尝试将数据上传到保管箱或类似的设备,在此处发布链接,并希望我们中的一些人有足够的资源是时候去了解它了。

import numpy as np
import pandas as pd
import random

num_sensors=int(100)
sensors= pd.DataFrame()
sensors['sensor id']=np.arange(0,num_sensors)
sensors['address id'] =np.arange(1000,1000+num_sensors)
#;ambda function not efficient on large datasets but irrelevant here
sensors['type']= sensors.apply( lambda x: "".join( [random.choice(['rain','temp','wind']) ] ), axis=1 )

num_measurements = 10
meas = pd.DataFrame()
meas['sensor id']= np.repeat(sensors['sensor id'], num_measurements )
meas['time'] = np.tile( np.arange(0,num_measurements ), num_sensors )
meas['value'] =np.random.rand(num_measurements * num_sensors )
#otherwise the index is copied from the other dataframe, so is not unique
meas=meas.reset_index(drop=True)

joined = pd.merge(sensors, meas, how='outer', on='sensor id')
pt = joined.pivot_table( index= ['sensor id','address id','time'], columns=['type'], values=['value']  ).reset_index()