使用Pandas我有一个df,它是14000行乘56列(关键字(我有一个1406项的关键字列表(full_keys(和一个使用关键字列表作为索引和列的空(0(数据帧(称为key_frame((所以1406x1406(
我想遍历df的每一行,对于该行中的每个关键字,增加该关键字与该行中存在的每个其他关键字在key_frame中的交集。
key_frame = pd.DataFrame(columns=full_keys, index=full_keys).fillna(0) # create empty df
for i, r in keywords.iterrows(): #iterate through each row in df
for index, rows in key_frame.iterrows(): #iterate through blank df to tabulate
if index in list(r): # if the index (which is a keyword) appears in row...
for x in r: #iterate through row and for each intersection loc[index, x] increment tally by 1
key_frame.loc[index, x]+=1
我也有这个,和上面一样,但评论行:
key_frame_2 = pd.DataFrame(columns=full_keys, index=full_keys).fillna(0)
for i, r in keywords.iterrows():
for x in full_keys: #iterate through list rather than key_frame, it's...faster?
if x in list(r):
for keyword in r:
key_frame_2.loc[x, keyword]+=1
感觉生疏,很喜欢一些指针!我知道有更好的方法。
假设keywords
数据帧仅包含来自full_keys
:的元素
>>> full_keys = ["A", "B", "C", "D", "E"]
>>> keywords
0 1 2
0 B A C
1 C B D
2 E C D
3 A D E
4 E A D
您可以首先创建一个DataFrame,该DataFrame为关键字中的每一行包含一行,其中包含所有关键字对的列表(包括重复的关键字对和所有排序中的关键字对(。我们使用itertools.product
:实现了这一点
import itertools
key_frame = keywords.apply(lambda row: list(itertools.product(row, repeat=2)), axis=1)
>>> key_frame
0 [(B, B), (B, A), (B, C), (A, B), (A, A), (A, C...
1 [(C, C), (C, B), (C, D), (B, C), (B, B), (B, D...
2 [(E, E), (E, C), (E, D), (C, E), (C, C), (C, D...
3 [(A, A), (A, D), (A, E), (D, A), (D, D), (D, E...
4 [(E, E), (E, A), (E, D), (A, E), (A, A), (A, D...
dtype: object
然后,将这些列表压平,得到所有对的序列,并对对进行计数(这基本上为您提供了关键字对的一维直方图(:
key_frame = key_frame.explode().value_counts()
>>> key_frame
(D, D) 4
(A, A) 3
(D, E) 3
...
(C, E) 1
(A, C) 1
(A, B) 1
dtype: int64
现在,为了将其转换为关键字的二维直方图,我们使用unstack()
,它要求索引是MultiIndex,而不是元组的索引:
key_frame.index = pd.MultiIndex.from_tuples(key_frame.index)
key_frame = key_frame.unstack()
>>> key_frame
A B C D E
A 3.0 1.0 1.0 2.0 2.0
B 1.0 2.0 2.0 1.0 NaN
C 1.0 2.0 3.0 2.0 1.0
D 2.0 1.0 2.0 4.0 3.0
E 2.0 NaN 1.0 3.0 3.0
在此阶段,key_frame
DataFrame包含所需DataFrame中的所有非零条目。这可能已经足够好了,但为了填充缺失的列、行或NaN条目,我们可以使用reindex()
和fillna()
:
key_frame = key_frame.reindex(full_keys, columns=full_keys).fillna(0)
>>> key_frame
A B C D E
A 3.0 1.0 1.0 2.0 2.0
B 1.0 2.0 2.0 1.0 0.0
C 1.0 2.0 3.0 2.0 1.0
D 2.0 1.0 2.0 4.0 3.0
E 2.0 0.0 1.0 3.0 3.0
这应该会给你一个与使用代码实现的DataFrame相同的DataFrame,但只花了一小部分时间——在相同的keywords
DataFrame(有100行和10列(上运行代码所花费的时间大约是这个解决方案的100倍。