Отображение списка в 1 и 0 - PullRequest
       22

Отображение списка в 1 и 0

1 голос
/ 15 октября 2019

У меня есть два списка my_genre и list_of_genres. Я хочу, чтобы функция проверяла, находится ли my_list[index] в list_of_genres, и конвертировала list_of_genres[index2] в 1, если это так.

list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller', 'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX', 'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']


my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

ожидаемый результат:

[0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0]
data type : np.array

В конечном итоге я хочу применить функцию, которая делает это, к столбцу панд, который содержит жанры.

Ответы [ 7 ]

5 голосов
/ 15 октября 2019

Numpy isin - это то, что вы ищете.

results = np.isin(list_of_genres, my_genre).astype(int)

То же самое для панд.

list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller', 'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX', 'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']
my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

df = pd.DataFrame({"genres" : list_of_genres})
df["my_genre"]  = df["genres"].isin(my_genre).astype(int)
print(df)
1 голос
/ 15 октября 2019

A map() решение на основе list:

ll = list(map(int, map(my_genre.__contains__, list_of_genres)))
print(ll)
# [0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

Для результата numpy.ndarray() вы можете использовать np.fromiter():

import numpy as np

arr = np.fromiter(map(my_genre.__contains__, list_of_genres), dtype=int)
print(arr)
# [0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0]

Для больших входов np.in() должно быть самым быстрым. Для входов такого размера подход map() работает в ~ 6 раз быстрее, чем np.isin(), в ~ 65 раз быстрее, чем решение pandas, и на ~ 40% быстрее, чем понимание.

%timeit np.isin(list_of_genres, my_genre).astype(int)                                                                                        
# 15.8 µs ± 385 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit np.fromiter(map(my_genre.__contains__, list_of_genres), dtype=int)                                                                   
# 2.55 µs ± 27.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit np.fromiter((my_genre.__contains__(x) for x in list_of_genres), dtype=int)                                                           
# 4.14 µs ± 19.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit df["genres"].isin(my_genre).astype(int)                                                                                              
# 167 µs ± 2.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Это может быть еще больше ускорено путем преобразования my_genre в set до применения оператора in / .__contains__:

%timeit np.fromiter(map(set(my_genre).__contains__, list_of_genres), dtype=int)                                                              
# 1.9 µs ± 7.17 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
0 голосов
/ 15 октября 2019

Вы можете использовать понимание списка как решение в 1 строку

bool_list = [1 if item in my_genre else 0 for item in list_of_genres]

Если вы новичок в этом и не совсем понимаете понимание списка, вы можете разбить его на цикл for

bool_list =[]
for item in list_of_genres:
    if(item in my_genre):
        bool_list.append(1)
    else:
        bool_list.append(0)
0 голосов
/ 15 октября 2019

Это должно сделать это как хороший маленький лайнер:

list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller', 'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX', 'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']
my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

result = np.array([int(my_genre.__contains__(n)) for n in list_of_genres])

Вывод:

[0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
0 голосов
/ 15 октября 2019

Если вы хотите использовать pandas в качестве тегов, вы можете сделать

import pandas as pd
list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy',
                  'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller',
                  'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX',
                  'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']

my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

df = pd.DataFrame({"genre": list_of_genres})

df["genre"].apply(lambda x: x in my_genre).astype(int)

# or even faster

df["genre"].isin(my_genre).astype(int)
0 голосов
/ 15 октября 2019

Попробуйте это,

>>> list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller', 'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX', 'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']


>>> my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

Вывод:

>>> [1 if el in my_genre else 0 for el in list_of_genres]

[0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
0 голосов
/ 15 октября 2019

Вот он, хотя ваш вопрос сформулирован плохо.

list_of_genres = ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy', 'Drama', 'Romance', 'Action', 'Thriller', 'Sci-Fi', 'Crime', 'Horror', 'Mystery', 'IMAX', 'Documentary', 'War', 'Musical', 'Western', 'Film-Noir']
my_genre = ['Action', 'Crime', 'Drama', 'Thriller']

idx = [1 if g in my_genre else 0 for g in list_of_genres]

Вывод:

Out[13]: [0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

Если вы хотите массив numpy, то просто преобразуйте его в один с помощью numpy.asarray(). А чтобы применить его к кадру данных, просто измените элементы my_genre и list_of_genres соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...