Python:使用df1的2列中的信息模拟Excel的索引匹配,以用于在df2中查找位置

时间:2019-06-13 09:50:46

标签: python indexing match vlookup

除其他外,我正在尝试处理大型数据集,这就是为什么我从Excel切换到Python的原因。我设法解决了大多数问题,但是,对于我看来很差的Google技能,以下问题似乎很复杂。

可用数据: 我有一个具有500 k行的pandas dataframe1。每行包含一个时间戳,一个机器号以及一个指示器(如果它是活动的)。 我还有另一个pandas dataframe2,它具有约3000万行(一年一秒钟)和60列(每台机器一列)。

目标:我想通过查看df1中的每一行来填充df2的空白矩阵。在df1中,我想使用时间戳信息在df2中找到相应的行,在df1中,我要使用机器编号在df2中找到相应的列,然后将值粘贴到df2

import pandas as pd

df_1 = pd.DataFrame({'timestamp':[1, 1, 4, 5],
                 'machine_number':[123, 789, 789, 123],
                 'active_inactive':[1, 0, 1, 0]})    
df_2 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':['', '', '', '', ''],
                 '789':['', '', '', '', '']})

模拟索引匹配后,我希望获得以下结果

df_3 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':[1, '', '', '', 0],
                 '789':[0, '', '', 1, '']})

最终,我想用最新的活动/不活动指示器填充空值,直到出现新的指示器:

df_4 = pd.DataFrame({'time':[1, 2, 3, 4, 5],
                 '123':[1, 1, 1, 1, 0],
                 '789':[0, 0, 0, 1, 1]})

但这又可能是我有一天要尝试解决的问题。

在此先感谢您提供任何有用的信息。

最佳 斯文

1 个答案:

答案 0 :(得分:0)

欢迎来到SO。因此,这个问题实际上比看起来要复杂一些。首先要了解的是,熊猫最好与“整洁”的数据(https://en.wikipedia.org/wiki/Tidy_data)配合使用。由于excel非常适合用于数据输入,而未针对分析进行优化(如您所知)。随着对数据帧进行编码的深入,您将学到更多有关此的知识,但是现在您只需要了解事物必须采用不同的格式才能正常工作。

因此,首先,您需要将第二个数据声名从宽格式转换为长格式(需要整理一下):

df_1 = pd.DataFrame({'timestamp':[1, 1, 4, 5],
                 'machine_number':[123, 789, 789, 123],
                 'active_inactive':[1, 0, 1, 0]})

df_2 = pd.DataFrame({'timestamp':[1, 2, 3, 4, 5], # note that I changed this name to 'timestamp' so
                                                  # it's the same in both dataframe
                 '123':['', '', '', '', ''],
                 '789':['', '', '', '', '']})

(df_2_melted = pd.melt(df_2, id_vars=['timestamp'], 
                             value_vars=['123', '789'], 
                             var_name='machine_number')
                 .drop(columns='value'))

df_2_melted['machine_number'] = df_2_melted['machine_number'].astype('int64')
# I had to change this column to 'int64' because the next operation won't work unless the
# columns are the same type

这就是你了

    timestamp   machine_number
0   1           123
1   2           123
2   3           123
3   4           123
4   5           123
5   1           789
6   2           789
7   3           789
8   4           789
9   5           789

然后可以将列“合并”在一起。这就像来自sql或Excel中的index_match / vlookup的联接操作:

merged = pd.merge(df_2_melted, df_1, how='left', on=['timestamp', 'machine_number'])

merged

    timestamp   machine_number  active_inactive
0   1           123             1.0
1   2           123             NaN
2   3           123             NaN
3   4           123             NaN
4   5           123             0.0
5   1           789             0.0
6   2           789             NaN
7   3           789             NaN
8   4           789             1.0
9   5           789             NaN

然后,如果要将其恢复为与原始数据帧相同的格式,则需要pivot使其退回(顾名思义,这就像来自excel的数据透视表一样):< / p>

merged.pivot(index='timestamp', columns='machine_number', values='active_inactive').reset_index(drop=True)

machine_number  123     789
0               1.0     0.0
1               NaN     NaN
2               NaN     NaN
3               NaN     1.0
4               0.0     NaN

话虽如此,您将希望所有内容都保持整洁的格式进行分析,因此,如果您最终希望将其以电子表格的形式写给其他人,我只建议您进行调整。