复杂的功能,用于获取一列与另一列的组合



我在pandas df

中有一个表格
id_x  id_y
a      b
b      c
a      c
d      a
x      a
m      b
c      z
a      k
b      q
d      w
a      w
q      v

如何阅读此表是:

A IS,A-B,A-C,A-K,A-W的组合类似于B(B-C,B-Q)等。我想编写一个从DF def test_func(id)

中获取ID_x的函数

并检查该ID的出现是否大于3,这可能是由df['id_x'].value_counts进行的。

例如

def test_func(id):
    if id_count >= 3:
       print 'yes'
       ddf = df[df['id_x'] == id]
       ddf.to_csv(id+".csv")
    else:
       print 'no'
       while id_count <3:
           # do something.(I've explained below what I have to do when count<3)

对B说,出现仅为2(即B-C和B-Q),小于3。

因此,在这种情况下,请查看" C"(来自ID_Y)是否具有任何组合。

C具有1个组合(C-Z),并且Q具有1组(Q-V)

因此,B应该与z和v。

链接
id_x   id_y
b       c
b       q
b       z
b       v

并将其存储在DDF2中,就像我们存储> 10。

也适用于特定的ID,如果我可以用ID的名称保存CSV。我希望我正确解释了我的问题,我对Python非常陌生,我不知道写功能,这是我的逻辑。

任何人都可以帮助我完成实施部分。预先感谢。

编辑:解决方案根据注释重新设计

import pandas as pd
def direct_related(df, values, column_names=('x', 'y')):
    rels = set()
    for value in values:
        for i, v in df[df[column_names[0]]==value][column_names[1]].iteritems():
            rels.add(v)
    return rels

def indirect_related(df, values, recursion=1, column_names=('x', 'y')):
    rels = direct_related(df, values, column_names)
    for i in range(recursion):
        rels = rels.union(direct_related(df, rels, column_names))
    return rels
def related(df, value, recursion=1, column_names=('x', 'y')):
    rels = indirect_related(df, [value], recursion, column_names)
    return pd.DataFrame(
        {
            column_names[0]: value,
            column_names[1]: list(rels)
        }
    )
def min_related(df, value, min_appearances=3, max_recursion=10, column_names=('x', 'y')):
    for i in range(max_recursion + 1):
        if len(indirect_related(df, [value], i, column_names)) >= min_appearances:
            return related(df, value, i, column_names)
    return None
df = pd.DataFrame(
    {
        'x': ['a', 'b', 'a', 'd', 'x', 'm', 'c', 'a', 'b', 'd', 'a', 'q'],
        'y': ['b', 'c', 'c', 'a', 'a', 'b', 'z', 'k', 'q', 'w', 'w', 'v']
    }
)
print(min_related(df, 'b', 3))

length的第一个过滤器 DataFrame(用于测试< 3

a = df.groupby('id_x').filter(lambda x: len(x) < 3)
print (a)
   id_x id_y
1     b    c
3     d    a
4     x    a
5     m    b
6     c    z
8     b    q
9     d    w
11    q    v

然后过滤 b和重命名列的位置:

a1 = a.query("id_x == 'b'").rename(columns={'id_y':'id'})
print (a1)
  id_x id
1    b  c
8    b  q

还过滤在不b的地方:

a2 = a.query("id_y != 'b'").rename(columns={'id_x':'id'})
print (a2)
   id id_y
1   b    c
3   d    a
4   x    a
6   c    z
8   b    q
9   d    w
11  q    v

然后由mergeid

b = pd.merge(a1,a2, on='id').drop('id', axis=1)
print (b)
  id_x id_y
0    b    z
1    b    v

最后一个concat由B过滤到新的DataFrame b

c = pd.concat([a.query("id_x == 'b'"), b])
print (c)
  id_x id_y
1    b    c
8    b    q
0    b    z
1    b    v

最新更新