Pandas DataFrame中的计算列

0 投票
1 回答
720 浏览
提问于 2025-04-18 08:24

我用以下代码创建了一个数据框:


data_series = {}
while not q.empty():
    (name, data_dict) = q.get()
    data_series[name] = pd.Series(data_dict)`
data_frame = pd.DataFrame(data_series)

#data_dict is of the format { MD5: [time_as_float1, time_as_float2] }
#I have multiple data_dicts stored in a queue (created by multiple worker threads)

我想要实现的目标大致是这样的:

1. 对于每个MD5,输出一下floghlogslog各自花了多少时间。(通过计算对应的time_as_float2和time_as_float1的差值)
2. 对于每个hlogflog,显示他们第一次看到某个MD5的时间(也就是最小的time_as_float1)和最后一次看到某个MD5的时间(也就是最大的time_as_float2)

数据框: 索引:395条记录,从0037B4F499705D725C2B3B00956B574E到FF11433CC64568110D3AD46037290725 数据列(总共3列): flog 220个非空值 hlog 175个非空值 slog 20个非空值 数据类型:对象(3) (Pdb) data_frame['hlog'] 0037B4F499705D725C2B3B00956B574E [1401808481.57, 1401808481.7] 016E73F1038CE46AF4A619453AC7DE70 [1401808491.38, 1401808491.51] 0250F3B15665E8B00F7D58CCA8C2C8F4 NaN 0260FA375596B150DF8B4D7E3CA2D934 NaN 03173B333E22CE63F6485AC87D616878 [1401808482.36, 1401808482.49]

我甚至不确定我构建数据框的方式是否正确,因为我觉得我的需求这么简单,应该是默认就能支持的。

1 个回答

1

你说得对,你构建数据框的方式不是很好。可以尝试利用pandas和numpy之间的强大互动。

我先创建数据框(在开始时就应该知道你会有多少行,这样性能会更好),然后再逐行填充数据。这个部分我无法改进,因为我没有python 3和queue

# first initialize dataframe
data_frame = pd.DataFrame(columns=['type', 'hash', 't0', 't1'], index=np.arange(10))

# this is now what would have to be inside the queue loop
data_dict = {'type': name, 'hash':md5hash,
             't0': times[0], 't1': times[1]}
name = "hlog"

data_series = pd.Series(data_dict)

data_frame.loc[0] = data_series
data_series[['t0', 't1']] += 0.5 # now I just quickly "fake" an additional loop to create more data
data_frame.loc[1] = data_series

现在我的数据集看起来是这样的:

   type hash   t0   t1
0  hlog  MD5  0.1  0.2
1  hlog  MD5  0.6  0.7
2   NaN  NaN  NaN  NaN
3   NaN  NaN  NaN  NaN
(...)

所以现在,拥有单独的t0t1列后,你的第一个问题就变得非常简单了:

data_frame['time-it-took'] = data_frame['t1'] - data_frame['t0']

第二个问题在这里也经常被回答:这是一种典型的groupby-apply组合,你可以在文档中找到很多相关信息: # 设置索引:类型 data_frame.set_index(['type'], inplace=True) # 按类型分组,并将最小的to作为值 data_frame['first-time'] = data_frame.groupby(level=0).apply(lambda x: x['t0'].min())

现在我的数据看起来是这样的(索引仍然设置为哈希类型):

     hash   t0   t1 time-it-took  first-time
type                                        
hlog  MD5  0.1  0.2          0.1         0.1
hlog  MD5  0.6  0.7          0.1         0.1
NaN   NaN  NaN  NaN          NaN         NaN

一旦你理解了这里发生了什么,我相信你可以用同样的方法找到't1'的最大值。

再次强调,关键是要正确设置数据框,这一点你应该多花时间去做。试着考虑一下你的数据应该以什么样的方式结构化才最合理。

撰写回答