我将包含HTTP事务的一些日志解析为Pandas DataFrame。每一行都是一个trasaction,因此一列具有IP地址,另一列具有主机名等。对于每一行(日志条目),我想将标题参数提取到列表中,并将该列表存储在列表中。该行的其他信息。
问题是:如何存储参数列表,以便可以轻松地与日志中的其余数据进行交叉引用?
为了举例,假设我有这个数据框,其中用户的宠物列表存储为字符串,我们想要解析各个动物并将其存储为列表。我们的想法是存储解析字符串的结果,以便实际的解析例程只需运行一次。
# Original Dataframe
User | PetsString
----------------------
Mary | 'dog/cat/rat'
John | 'dog/lizard'
方法1)我可以在数据框中添加一列,并将列表存储在此列中。
User | PetsString | PetsList
--------------------------------------------
Mary | 'dog/cat/rat' | ['dog','cat','rat']
John | 'dog/lizard' | ['dog','lizard']
方法2)我可以创建另一个包含列表条目的数据框,其中一列指示原始数据框中日志在corss -ferencing中的位置。我想避免这种情况,因为我认为同时迭代两个数据帧比迭代单个大型列表要慢。 E.g。
User | PetsString
-----------------------
Mary | 'dog/cat/rat'
John | 'dog/lizard'
#Separate DataFrame for cross-reference
User | Pet
-----------------
Mary | 'dog'
Mary | 'cat'
Mary | 'rat'
John | 'dog'
John | 'lizard'
方法3)有人建议在我现有的数据框中添加50列,并将每个列表项存储在其中一列中。我不希望有超过50个标头参数。这似乎是速度最佳的,但在列数方面存在令人讨厌的限制。 E.g。
User | PetsString | Pet0 | Pet1 | Pet2
------------------------------------------------------
Mary | 'dog/cat/rat' | 'dog' | 'cat' | 'rat'
John | 'dog/lizard' | 'dog' | 'lizard' |
我有两个问题:
(i)假设我需要计算一个函数来读取一行和相应列表中的所有参数,这三个布局中的哪一个是速度最佳的?
(ii)其中哪些是空间最佳的?我不确定Pandas如何使用对象,但我相信如果我使用方法1,Pandas将创建一个与最长列表一样宽的列。同样,方法3必须为完整的Pet2'分配空间。专栏,即使约翰没有一个
我知道很多这些东西可能特定于我的特定处理器,缓存大小,用例等,但即使是对权衡的一般理解对我来说也是非常有用的
提前感谢您的帮助!
答案 0 :(得分:2)
Pandas DataFrame列中的值存储在同类numpy数组中。请考虑以下事项:
In [95]: pd.DataFrame({'a': ['foo', 'bar/baz']}).a.dtype
Out[95]: dtype('O')
In [96]: pd.DataFrame({'a': [['foo'], ['bar', 'baz']]}).a.dtype
Out[96]: dtype('O')
这表明:
当您存储不同长度的字符串时,Pandas使用numpy对象数组(numpy也有字符串数组用于同等固定大小的字符串,但Pandas不使用它们。)
< / LI>存储列表时,Pandas也使用numpy对象数组。
基于此,我认为您的第一个选择将具有良好的内存和速度性能。 Pandas和numpy优于常规Python数据结构,例如巨大的数字序列,其中单个数字对象的Python开销很大。字符串的Python list
非常有效,而且(非固定大小)字符串的数组并不具有优势。
事实上,您可能会考虑Pandas是否在普通的Python上提供任何优势。为什么不将dict
映射到list
字符串的字符串,例如?