Фильтруйте строки данных в панде, если какое-либо значение в списке внутри фрейма находится в другом списке

>>> l = [1,2,3,4,5,6]

>>> zip(l,l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

>>> zip(l,l[1:])[::2]
[(1, 2), (3, 4), (5, 6)]

>>> [a+b for a,b in zip(l,l[1:])[::2]]
[3, 7, 11]

>>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]]
['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11']
4
задан Ary Jazz 16 January 2019 в 09:42
поделиться

5 ответов

Избегайте серии списков

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

df = pd.DataFrame({'album_id': [66562, 114582, 4846, 1709, 59239],
                   'categories': ['480.494', '128', '5', '9', '105.104']})

split = df['categories'].str.split('.', expand=True).add_prefix('split_').astype(float)
df = df.join(split)

print(df)
#    album_id categories  split_0  split_1
# 0     66562    480.494    480.0    494.0
# 1    114582        128    128.0      NaN
# 2      4846          5      5.0      NaN
# 3      1709          9      9.0      NaN
# 4     59239    105.104    105.0    104.0

L = [480, 9, 104]
res = df[df.filter(regex='^split_').isin(L).any(1)]

print(res)
#    album_id categories  split_0  split_1
# 0     66562    480.494    480.0    494.0
# 3      1709          9      9.0      NaN
# 4     59239    105.104    105.0    104.0
0
ответ дан jpp 16 January 2019 в 09:42
поделиться

Другой метод:

my_list = [480, 9, 104]
pat = r'({})'.format('|'.join(str(i) for i in my_list))
#'(480|9|104)' <-- This is how the pat looks like
df.loc[df.split_categories.astype(str).str.extract(pat, expand=False).dropna().index]

Или:

pat = '|'.join(r"\b{}\b".format(x) for x in my_list)
df[df.split_categories.astype(str).str.contains(pat,na=False)]

    album_id    categories  split_categories
0   66562       480.494     [480, 494]
3   1709        9.000       [9]
4   59239       105.104     [105, 104]

Это будет работать с колонками split_categories и categories.

0
ответ дан anky_91 16 January 2019 в 09:42
поделиться

Вы можете расширить внутренний список и проверить, содержатся ли any элементы во внутренних списках в [480, 9, 104]:

l = [480, 9, 104]
df[df.categories.str.split('.', expand=True).isin(map(str,l)).any(axis=1)]

   album_id  categories split_categories
0     66562     480.494        [480,494]
3      1709       9.000              [9]
4     59239     105.104        [105,104]
0
ответ дан yatu 16 January 2019 в 09:42
поделиться

Вы можете преобразовать каждый список в наборы, получить пересечение и преобразовать в bool:

L = [480, 9, 104]
mask = np.array([bool(set(map(int, x)) & set(L))  for x in df['split_categories']])

Или преобразовать list column в DataFrame, привести к плаванию и сравнить с isin:

df1 = pd.DataFrame(df['split_categories'].values.tolist(), index=df.index)
mask = df1.astype(float).isin(L).any(axis=1)
<час>
df = df[mask]
print (df)
  album_id categories split_categories
0    66562    480.494       [480, 494]
3     1709          9              [9]
4    59239    105.104       [105, 104]
0
ответ дан jezrael 16 January 2019 в 09:42
поделиться

Использование:

print(df[~(df['split_categories'].isin([480, 9, 104])).any()])

Выход:

  album_id categories split_categories
0    66562    480.494       [480, 494]
3     1709          9              [9]
4    59239    105.104       [105, 104]
0
ответ дан U9-Forward 16 January 2019 в 09:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: