затем сгруппируйте значения в строках списка типов, чтобы заполнить новый столбец - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть такой фрейм данных

data = {'clusterId':[1,1,2,2,2], 'IM1':[[0,1], [2,3], [3,5],[4,5],[3,6]],
        'IM2':[[1,2],[2,0],[9,0],[8,7],[8,2]]} 
df = pd.DataFrame(data) 


clusterId  IM1    IM2   
1         [0,1]   [1,2]
1         [2,3]   [2,0]
2         [3,5]   [9,0]
2         [4,5]   [8,7]
2         [3,6]   [8,2]

Я хочу заполнить новый столбец сказать "существует", если какой-либо элемент в списке IM1, который попадает в тот же кластер, совпадает друг с другом

clusterId  IM1    IM2    Exists
1         [0,1]   [1,2]   N
1         [2,3]   [2,0]   N
2         [3,5]   [9,0]   Y
2         [4,5]   [8,7]   Y
2         [7,6]   [8,2]   N

тогда я хочу обновить столбец Exists, где значения «N» основаны на значениях в cloumn IM2, например, если любое из значений в списке соответствует

, поэтому результирующий кадр данных будет выглядеть следующим образом

clusterId  IM1    IM2    Exists
1         [0,1]   [1,2]   Y
1         [2,3]   [2,0]   Y
2         [3,5]   [9,0]   Y
2         [4,5]   [8,7]   Y
2         [7,6]   [8,2]   Y

есть ли python способ сделать это. Любая помощь будет высоко оценена

1 Ответ

1 голос
/ 25 апреля 2020

Это будет делать то, что вы ищете. Я исключил промежуточные шаги столбца, используя функцию. Вы можете добавить их обратно, отредактировав нужную функцию -

import numpy as np
import pandas as pd

data = {'clusterId':[1,1,2,2,2], 'IM1':[[0,1], [2,3], [3,5],[4,5],[3,6]],
        'IM2':[[1,2],[2,0],[9,0],[8,7],[8,2]]} 
df = pd.DataFrame(data) 

def concat_list(list1): #Flatten the array values by clusterId
    return np.concatenate(list1)

def count_element(row): #count row wise element frequency

    list1 = row['array1']
    element1 = row['IM1']

    t1 = np.count_nonzero(list1 == element1[0])
    t2 = np.count_nonzero(list1 == element1[1])
    if t1 >=2 or t2 >=2: result1 = "Y" 
    else: result1 = "N"

    list2 = row['array2']
    element2 = row['IM2']

    t3 = np.count_nonzero(list2 == element2[0])
    t4 = np.count_nonzero(list2 == element2[1])
    if t3 >=2 or t4 >=2: result2 = "Y" 
    else: result2 = "N"

    if (result1 == 'N' and result2 == 'N'):
        result = 'N'
    else: result = 'Y'

    return result

for clusterId in cluster_list:
    print(clusterId)
    df2 = df.loc[df['clusterId'] == clusterId].reset_index()
    array1 = concat_list(df2['IM1'])
    array2 = concat_list(df2['IM2'])
    mask = df.clusterId==clusterId
    df.loc[mask, 'array1']=df[mask].apply(lambda x: array1,axis=1) # Add array based on IM1 
    df.loc[mask, 'array2']=df[mask].apply(lambda x: array2,axis=1)  # Add array based on IM2

df['exist_final'] = df.apply(lambda row: count_element(row), axis = 1)
...