Pandas:如何将数据帧中行列列表与Pandas(非for循环)进行比较?

2024-09-27 04:10:11 发布

您现在位置:Python中文网/ 问答频道 /正文

数据帧

df = pd.DataFrame({'A': [['gener'], ['gener'], ['system'], ['system'], ['gutter'], ['gutter'], ['gutter'], ['gutter'], ['gutter'], ['gutter'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum'], ['aluminum', 'toledo']], 'B': [['gutter'], ['gutter'], ['gutter', 'system'], ['gutter', 'guard', 'system'], ['ohio', 'gutter'], ['gutter', 'toledo'], ['toledo', 'gutter'], ['gutter'], ['gutter'], ['gutter'], ['how', 'to', 'instal', 'aluminum', 'gutter'], ['aluminum', 'gutter'], ['aluminum', 'gutter', 'color'], ['aluminum', 'gutter'], ['aluminum', 'gutter', 'adrian', 'ohio'], ['aluminum', 'gutter', 'bowl', 'green', 'ohio'], ['aluminum', 'gutter', 'maume', 'ohio'], ['aluminum', 'gutter', 'perrysburg', 'ohio'], ['aluminum', 'gutter', 'tecumseh', 'ohio'], ['aluminum', 'gutter', 'toledo', 'ohio']]}, columns=['A', 'B'])

它的样子

我有一个包含两列列表的数据框。

                     A                                      B
0              [gener]                               [gutter]
1              [gener]                               [gutter]
2             [system]                       [gutter, system]
3             [system]                [gutter, guard, system]
4             [gutter]                         [ohio, gutter]
5             [gutter]                       [gutter, toledo]
6             [gutter]                       [toledo, gutter]
7             [gutter]                               [gutter]
8             [gutter]                               [gutter]
9             [gutter]                               [gutter]
10          [aluminum]    [how, to, instal, aluminum, gutter]
11          [aluminum]                     [aluminum, gutter]
12          [aluminum]              [aluminum, gutter, color]
13          [aluminum]                     [aluminum, gutter]
14          [aluminum]       [aluminum, gutter, adrian, ohio]
15          [aluminum]  [aluminum, gutter, bowl, green, ohio]
16          [aluminum]        [aluminum, gutter, maume, ohio]
17          [aluminum]   [aluminum, gutter, perrysburg, ohio]
18          [aluminum]     [aluminum, gutter, tecumseh, ohio]
19  [aluminum, toledo]       [aluminum, gutter, toledo, ohio]

问题

如果我有列表列,是否有pandas函数允许我对整个列表数组进行操作,以检查交叉点并将布尔值或交叉值作为新序列返回?

例如,我希望熊猫有一个类似的:

def intersection(df, col1, col2, return_type='boolean'):
    if return_type == 'boolean':
        df = df[[col1, col2]]
        s = []
        for idx in df.iterrows():
            s.append(any([phrase in idx[1][0] for phrase in idx[1][1]]))
        S = pd.Series(s)
        return S
    elif return_type == 'word':
        df = df[[col1, col2]]
        s = []
        for idx in df.iterrows():
            s.append(', '.join([word for word in list(set(idx[1][0]).intersection(set(idx[1][1])))]))
        S = pd.Series(s)
        return S

#Create column C in df
df['C'] = intersection(df, 'A', 'B', 'word')

。。。无需编写自己的函数或使用for循环。我觉得必须有一种更简单的方法来比较同一行中两列的列表,看看它们是否相交。

我可以用for循环来完成,但它对我来说很难看

for循环返回boolean序列:

for idx in df.iterrows():
    any([phrase in idx[1][0] for phrase in idx[1][1]])

产生:

False
False
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

或者,使用sets查找相交单词:

for idx in df.iterrows():
    ', '.join([word for word in list(set(idx[1][0]).intersection(set(idx[1][1])))])

''
''
'system'
'system'
'gutter'
'gutter'
'gutter'
'gutter'
'gutter'
'gutter'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'aluminum'
'toledo, aluminum'

Tags: intruedf列表forreturnsystemword
2条回答

要检查df.A中的每个项是否包含在df.B中:

>>> df.apply(lambda row: all(i in row.B for i in row.A), axis=1)
# OR: ~(df['A'].apply(set) - df['B'].apply(set)).astype(bool)
0     False
1     False
2      True
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13     True
14     True
15     True
16     True
17     True
18     True
19     True
dtype: bool

为了得到工会:

df['intersection'] = [list(set(a).intersection(set(b))) for a, b in zip(df.A, df.B)]

>>> df
                     A                                      B        intersection
0              [gener]                               [gutter]                  []
1              [gener]                               [gutter]                  []
2             [system]                       [gutter, system]            [system]
3             [system]                [gutter, guard, system]            [system]
4             [gutter]                         [ohio, gutter]            [gutter]
5             [gutter]                       [gutter, toledo]            [gutter]
6             [gutter]                       [toledo, gutter]            [gutter]
7             [gutter]                               [gutter]            [gutter]
8             [gutter]                               [gutter]            [gutter]
9             [gutter]                               [gutter]            [gutter]
10          [aluminum]    [how, to, instal, aluminum, gutter]          [aluminum]
11          [aluminum]                     [aluminum, gutter]          [aluminum]
12          [aluminum]              [aluminum, gutter, color]          [aluminum]
13          [aluminum]                     [aluminum, gutter]          [aluminum]
14          [aluminum]       [aluminum, gutter, adrian, ohio]          [aluminum]
15          [aluminum]  [aluminum, gutter, bowl, green, ohio]          [aluminum]
16          [aluminum]        [aluminum, gutter, maume, ohio]          [aluminum]
17          [aluminum]   [aluminum, gutter, perrysburg, ohio]          [aluminum]
18          [aluminum]     [aluminum, gutter, tecumseh, ohio]          [aluminum]
19  [aluminum, toledo]       [aluminum, gutter, toledo, ohio]  [aluminum, toledo]

只要使用由pandas支持的apply函数,就可以了。

由于可以有两列以上的列用于相交,因此可以这样准备辅助函数,然后将其应用于DataFrame.apply函数(请参见http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html,注意选项axis=1表示“跨系列”,而axis=0表示“沿系列”,其中 序列只是数据框中的一列)。然后,列中的每一行作为iterableSeries对象传递给应用的函数。

def intersect(ss):
    ss = iter(ss)
    s = set(next(ss))
    for t in ss:
        s.intersection_update(t) # `t' must not be a `set' here, `list' or any `Iterable` is OK
    return s

res = df.apply(intersect, axis=1)

>>> res
0                     {}
1                     {}
2               {system}
3               {system}
4               {gutter}
5               {gutter}
6               {gutter}
7               {gutter}
8               {gutter}
9               {gutter}
10            {aluminum}
11            {aluminum}
12            {aluminum}
13            {aluminum}
14            {aluminum}
15            {aluminum}
16            {aluminum}
17            {aluminum}
18            {aluminum}
19    {aluminum, toledo}

您可以对辅助函数的结果进行进一步的操作,或者类似地进行一些更改。

希望这有帮助。

相关问题 更多 >

    热门问题