2017-08-02 1 views
0

J'ai deux dataframes comme ceci:correspondant à deux sous-chaînes dataframes

[in]print(training_df.head(n=10)) 

[out] 
          product_id 
transaction_id      
0000001     [P06, P09] 
0000002   [P01, P05, P06, P09] 
0000003     [P01, P06] 
0000004     [P01, P09] 
0000005     [P06, P09] 
0000006     [P02, P09] 
0000007   [P01, P06, P09, P10] 
0000008     [P03, P05] 
0000009     [P03, P09] 
0000010   [P03, P05, P06, P09] 

[in]print(testing_df.head(n=10)) 

[out] 
        product_id 
transaction_id     
001      [P01] 
002     [P01, P02] 
003    [P01, P02, P09] 
004     [P01, P03] 
005    [P01, P03, P05] 
006    [P01, P03, P07] 
007    [P01, P03, P08] 
008     [P01, P04] 
009    [P01, P04, P05] 
010    [P01, P04, P08] 

Chaque ligne du testing_df est un « sous-chaîne » possible d'une ligne dans le training_df. Je voudrais trouver tous les résultats et renvoyer les listes possibles de formation_df pour chaque liste dans testing_df. Il serait utile que je puisse retourner un dictionnaire où les clés sont le transaction_id de testing_df et toutes les valeurs possibles sont "matches" dans le training_df. (Chaque liste dans le training_df devrait être une valeur plus longue que la liste correspondante dans le test_df).

J'ai essayé:

# Find the substrings that match 
matches = [] 

for string in training_df: 
    results = [] 
    for substring in testing_df: 
     if substring in string: 
      results.append(substring) 
    if results: 
     matches.append(results) 

Toutefois, ce travail ne marche pas, il ne retourne que le nom de la colonne 'Product_ID'.

J'ai essayé aussi:

# Initialize a list to store the matches between incomplete testing_df and training_df 
matches = {} 

# Compare the "incomplete" testing lists to the training set 
for line in testing_df.product_id: 
    for line in training_df.product_id: 
     if line in testing_df.product_id in line in training_df.product_id: 
      matches[line] = training_df[training_df.product_id.str.contains(line)] 

Cependant, cette lance une erreur TypeError: unhashable type: 'list'

+0

Je pense que le problème est les parenthèses. Par exemple, "P01" est une sous-chaîne de "[P01, P06]" mais "[P01]" ne l'est pas. Vous pourriez essayer la sous-chaîne [1: -1] au lieu de la sous-chaîne afin de vous débarrasser des parenthèses. – csander

+0

@csander J'ai essayé 'matches = [] pour chaîne en training_df [1: -1]: résultats = [] pour sous-chaîne testing_df [1: -1]: si sous-chaîne dans la chaîne: results.append (substring) si résultats: matches.append (résultats) 'mais cela n'a pas fonctionné non plus – zsad512

+0

Non, vous ne voulez pas découper le DataFrame, vous voulez découper la sous-chaîne – csander

Répondre

1

Je pense que le problème est entre crochets. Le problème est que in vérifie si un élément est dans une liste, pas si une liste est un sous-ensemble d'une autre. Vous pouvez convertir les deux listes en ensembles, puis vérifier s'il s'agit de sous-ensembles les uns des autres. Vous pouvez également utiliser l'indexation avancée pour préserver le transaction_id:

training_df = pd.DataFrame([ 
    ['0000001', ['P06', 'P09']], 
    ['0000002', ['P01', 'P05', 'P06', 'P09']], 
    ['0000003', ['P01', 'P06']], 
    ['0000004', ['P01', 'P09']], 
    ['0000005', ['P06', 'P09']], 
    ['0000006', ['P02', 'P09']], 
    ['0000007', ['P01', 'P06', 'P09', 'P10']], 
    ['0000008', ['P03', 'P05']], 
    ['0000009', ['P03', 'P09']], 
    ['0000010', ['P03', 'P05', 'P06', 'P09']], 
], columns=['transaction_id', 'product_id']) 

testing_df = pd.DataFrame([ 
    ['001', ['P01']], 
    ['002', ['P01', 'P02']], 
    ['003', ['P01', 'P02', 'P09']], 
    ['004', ['P01', 'P03']], 
    ['005', ['P01', 'P03', 'P05']], 
    ['006', ['P01', 'P03', 'P07']], 
    ['007', ['P01', 'P03', 'P08']], 
    ['008', ['P01', 'P04']], 
    ['009', ['P01', 'P04', 'P05']], 
    ['010', ['P01', 'P04', 'P08']], 
], columns=['transaction_id', 'product_id']) 

matches = {} 
for testing_id in testing_df.product_id: 
    testing_id_set = set(testing_id) 
    contains_id = training_df.product_id.apply(lambda id: testing_id_set.issubset(set(id))) 
    matches[str(testing_id)] = contains_id 
+0

Les fichiers testing_df et training_df sont déjà formatés en tant que données pandas. Quand j'essaie 'matches = {} pour testing_id dans testing_df.product_id: correspond à [testing_id] = training_df [training_df.product_id.str.contains (test_id [1: -1])]' il retourne simplement un dictionnaire vide – zsad512

+0

I inclus les définitions pour montrer les données que je testais avec. Si cela ne fonctionne pas pour vous, à quoi ressemblent vos trames de données? – csander

+0

Les crochets sont à l'extérieur de sorte par exemple la ligne 1, TRANSACTION_ID 001, la colonne product_id est la suivante: '[ « P01 », « P02 », « P03 »] ' – zsad512