Условно выровняйте два кадра данных, чтобы получить столбец, переданный как условие в numpy, где - PullRequest
0 голосов
/ 27 января 2019

Я пришел из фона SQL и новичок в Python. Я уже некоторое время пытаюсь понять, как решить эту конкретную проблему, и не могу ничего придумать.

Вот мои данные

from pandas import DataFrame
import numpy as np

Names1 = {'First_name': ['Jon','Bill','Billing','Maria','Martha','Emma']}
df = DataFrame(Names1,columns=['First_name'])
print(df)

names2 = {'name': ['Jo', 'Bi', 'Ma']}
df_2 = DataFrame(names2,columns=['name'])
print(df_2)

Результаты к этому:

   First_name
0        Jon
1       Bill
2    Billing
3      Maria
4     Martha
5       Emma
  name
0   Jo
1   Bi
2   Ma

Этот код помогает мне определить в df, какое First_name начинается с кортежа из df_2

df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), 'true', df['First_name'])

Результаты к этому:

First_name  like_flg
0   Jon     true
1   Bill    true
2   Billing true
3   Maria   true
4   Martha  true
5   Emma    Emma

Я бы хотел, чтобы в окончательном выводе кадра данных значение like_flg было установлено равным значению кортежа, с которым сравнивается поле First_name. Ниже приведен окончательный желаемый результат:

First_name  like_flg
0   Jon     Jo
1   Bill    Bi
2   Billing Bi
3   Maria   Ma
4   Martha  Ma
5   Emma    Emma

Вот что я пробовал до сих пор

df['like_flg'] = np.where(df['First_name'].str.startswith(tuple(list(df_2['name']))), tuple(list(df_2['name'])), df['First_name'])

приводит к этой ошибке:

`ValueError: operands could not be broadcast together with shapes (6,) (3,) (6,)` 

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

Есть ли способ условно выровнять кадры данных, чтобы заполнить столбцы, начинающиеся с кортежа?

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

Спасибо всем заранее!

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Если ваши начальные строки отличаются по длине, вы можете использовать .str.extract

df['like_flag'] = df['First_name'].str.extract('^('+'|'.join(df_2.name)+')')
df['like_flag'] = df['like_flag'].fillna(df.First_name)  # Fill non matches.

Я изменил df_2, чтобы он был

  name
0   Jo
1   Bi
2  Mar

, что приводит к:

  First_name like_flag
0        Jon        Jo
1       Bill        Bi
2    Billing        Bi
3      Maria       Mar
4     Martha       Mar
5       Emma      Emma
0 голосов
/ 27 января 2019

Делать с numpy find

v=df.First_name.values.astype(str)
s=df_2.name.values.astype(str)

df_2.name.dot((np.char.find(v,s[:,None])==0))
array(['Jo', 'Bi', 'Bi', 'Ma', 'Ma', ''], dtype=object)

Тогда мы просто присваиваем его обратно

df['New']=df_2.name.dot((np.char.find(v,s[:,None])==0))
df.loc[df['New']=='','New']=df.First_name
df
  First_name   New
0        Jon    Jo
1       Bill    Bi
2    Billing    Bi
3      Maria    Ma
4     Martha    Ma
5       Emma  Emma
0 голосов
/ 27 января 2019

Вы можете использовать np.where,

df['like_flg'] = np.where(df.First_name.str[:2].isin(df_2.name), df.First_name.str[:2], df.First_name)

    First_name  like_flg
0   Jon         Jo
1   Bill        Bi
2   Billing     Bi
3   Maria       Ma
4   Martha      Ma
5   Emma        Emma
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...