Pandas根据另一个单元格更改单元格值

时间:2016-07-19 11:19:54

标签: python python-3.x pandas dataframe

我目前正在格式化来自两个不同数据集的数据。 其中一个数据集反映了人们按小时计算的观察数量,第二个数据集是基于5分钟间隔内生成的wifi日志的人数。

将这两个数据帧合并为一个之后,我遇到了这样的问题:每小时(“10:00:00”)有来自原始集合的数据,但是其他数据(每隔5分钟就像“10:47: 14“)不包括这些数据。

以下是合并数据框的外观:

        room       time              con     auth  capacity    %     Count  module    size 
0       B002    Mon Nov 02 10:32:06  23      23       90       NaN    NaN   NaN        NaN`  
1       B002    Mon Nov 02 10:37:10  25      25       90       NaN    NaN   NaN        NaN`  
12527   B002    Mon Nov 02 10:00:00  NaN     NaN      90       50%    45.0  COMP30520   60`  
12528   B002    Mon Nov 02 11:00:00  NaN     NaN      90       0%     0.0   COMP30520   60`

有没有办法让我浏览数据框并从11:00:00找到有关“占用”,“占用数量”,“模块”和“大小”的所有信息,并将其写入所有单元格是同一天,小时是在10:00:00到10:59:59之间?

这样我就可以获得每一行的所有信息,然后让我根据“天”和“小时”收集min()max()median()。< / p>

要回答原始数据框的评论,这里有:
第一个数据框:

    time                room    module      size
0   Mon Nov 02 09:00:00 B002    COMP30190   29
1   Mon Nov 02 10:00:00 B002    COMP40660   53

第二个数据框:

        room    time                  con   auth  capacity  %     Count
0       B002    Mon Nov 02 20:32:06   0     0     NaN       NaN   NaN
1       B002    Mon Nov 02 20:37:10   0     0     NaN       NaN   NaN
2       B002    Mon Nov 02 20:42:12   0     0     NaN       NaN   NaN
12797   B008    Wed Nov 11 13:00:00   NaN   NaN   40        25    10.0
12798   B008    Wed Nov 11 14:00:00   NaN   NaN   40        50    20.0
12799   B008    Wed Nov 11 15:00:00   NaN   NaN   40        25    10.0

这就是将这两个数据帧合并在一起的方式:

DFinal = pd.merge(DF, d3, left_on=["room", "time"], right_on=["room", "time"], how="outer", left_index=False, right_index=False)

对此的任何帮助将不胜感激。

非常感谢,

-Romain

3 个答案:

答案 0 :(得分:2)

开始的地方:

b = df[(df['time'] > X) & (df['time'] < Y)]

选择X和Y时间内的所有元素

然后

df.loc[df['column_name'].isin(b)]

为您提供所需的行(即 - 在X和Y之间),您可以根据需要分配。 我想您想要将所选行的值分配给行号X的值<?p>

希望有所帮助。

请注意,这些功能是从中剪切和粘贴作业 [1] Filter dataframe rows if value in column is in a set list of values
[2] Select rows from a DataFrame based on values in a column in pandas

答案 1 :(得分:1)

如果我理解正确,您希望使用给定小时内可用的相应最近数据点填充合并数据框中的所有缺失值。在过去,我使用pandas.cut变量做了类似的时间序列,但我似乎无法找到它,反正它并不是很好。

虽然我不完全确定,但pandas数据框的fillna方法可能就是您想要的(docs here)。

让您的两个数据框命名为df_hourdf_cinq,您将它们合并为:

df = pd.merge(df_hour, df_cinq, left_on=["room", "time"], right_on=["room", "time"], how="outer", left_index=False, right_index=False)

然后将索引更改为时间并对其进行排序:

df.set_index('time',inplace=True)
df.sort_index(inplace=True)

fillna方法有一个名为&#39;方法&#39;可以有这些值(2):

   Method                 Action  
 pad / ffill          Fill values forward  
 bfill / backfill     Fill values backward  
 nearest              Fill from the nearest index value  

使用它来进行前向填充(即缺失值用帧中的前一个值填充):

df.fillna(method='ffill', inplace=True)

您的数据存在的问题是,属于5分钟观察的非工作时间内的所有缺失数据都将填充过时的数据点。您可以使用limit选项来限制要填写的连续数据点的数量,但我不知道它对您是否有用。

这是我作为玩具示例写的完整脚本:

import pandas as pd
import random


hourly_count = 8 #workhours 
cinq_count = 24 * 12 # 1day

hour_rng = pd.date_range('1/1/2016-09:00:00', periods = hourly_count, freq='H')
cinq_rng = pd.date_range('1/1/2016-00:02:53', periods = cinq_count,
                            freq='5min')

roomz = 'room0 room1 secretroom'.split()

hourlydata = {'col1': [], 'col2': [], 'room': []}
for i in range(hourly_count):
    hourlydata['room'].append(random.choice(roomz))
    hourlydata['col1'].append(random.random())
    hourlydata['col2'].append(random.randint(0,100))


cinqdata = {'col3': [], 'col4': [], 'room': []}
frts = 'apples oranges peaches grapefruits whatmore'.split()
vgtbls = 'onion1 onion2 onion3 onion4 onion5 onion0'.split()
for i in range(cinq_count):
    cinqdata['room'].append(random.choice(roomz))
    cinqdata['col3'].append(random.choice(frts))
    cinqdata['col4'].append(random.choice(vgtbls))

hourlydf = pd.DataFrame(hourlydata)
hourlydf['time'] = hour_rng
cinqdf = pd.DataFrame(cinqdata)
cinqdf['time'] = cinq_rng

df = pd.merge(hourlydf, cinqdf, left_on=['room','time'], right_on=['room',
    'time'], how='outer', left_index=False, right_index=False)

df.set_index('time',inplace=True)
df.sort_index(inplace=True)
df.fillna(method='ffill', inplace=True)
print(df['2016-1-1 09:00:00':'2016-1-1 17:00:00'])

答案 2 :(得分:0)

实际上我能够解决这个问题:

首先:在“时间”功能上使用分区,以便生成两个额外的列,一个用于在“时间”中显示,一个用于小时 “时间”专栏。 我使用lambda函数来获取这些列:

df['date'] = df['date'].map(lambda x: x[10:-6])
df['time'] = df['time'].map(lambda x: x[8:-8])

基于这两个新列,我修改了数据帧的合并方式。

这是我用来修复它的代码:

dataframeFinal = pd.merge(dataframe1, dataframe2, left_on=["room", "date", "hour"],
                right_on=["room", "date", "hour"], how="outer",
                left_index=False, right_index=False, copy=False)

在合并之后,我最终得到了重复的时间列('time_y'和“time_x”) 所以我将NaN值替换如下:

dataframeFinal.time_y.fillna(dataframeFinal.time_x, inplace=True)

现在列“time_y”包含所有时间值,不再有NaN。 我不需要“time_x”列,因此我将其从数据框中删除

dataframeFinal = dataframeFinal.drop('time_x', axis=1)