Цикл Pandas для numpy . Numpy считает ненулевые вхождения строки в массиве

#python #pandas #dataframe #count

#python #pandas #фрейм данных #количество

Вопрос:

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

   Column1(int) Column2(str)  Column3(str)
0     2             02            34
1     2             34            02
2     2             80            85
3     2             91            09
4     2             09            34
  

При использовании циклов pandas я использую следующий код. Если Column1 = 2, count how many times Column2 occurs in Column 3 and assign the count() to Column4 :

 import pandas as pd

for index in df.index:
    if df.loc[index, "Column"] == 2:
        df.loc[index, "Column4"] = df.loc[
            df.Column3 == df.loc[index, "Column2"], "Column3"
        ].count()
  

Я пытаюсь использовать методы NumPy и array для повышения эффективности. Я пытался перевести метод, но безуспешно.

 import numpy as np

# turn Column3 to array
array = df.loc[:, "Column3"].values

index = df.index
df.assign(
    Column4=lambda x: np.where(
        (x["Column1"] == 2), np.count_nonzero(array == df.loc[index, "Column2"]), "F"
    )
)
  

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

   Column1(int) Column2(str)  Column3(str)  Column4(int)
0     2             02            34           1
1     2             34            02           2
2     2             80            85           0
3     2             91            09           0
4     2             09            34           1
  

Комментарии:

1. каким должно быть значение в Column4 , если значение в Column1 не равно 2?

2. О, извините, это должно быть ‘F’

Ответ №1:

Вы можете использовать pd.Series.value_counts on Column3 и использовать его как отображение для Column2 , вы можете передать Series объект pd.Series.map , пропуская значения с pd.Series.fillna помощью with 0

 s = df['Column2'].map(df['Column3'].value_counts()).fillna(0)
df.loc[df['Column1'].eq(2), 'Column4'] = s
df['Column4'] = df['Column4'].fillna('F') 
# Fills with 'F' where `Column1` is not equal to 2.

   Column1  Column2  Column3  Column4
0        2        2       34      1.0
1        2       34        2      2.0
2        2       80       85      0.0
3        2       91        9      0.0
4        2        9       34      1.0
  

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

 s = df['Column2'].map(df['Column3'].value_counts()).fillna(0)
df['Column4'] = np.where(df['Column1'].eq(2), s, 'F')
  

Комментарии:

1. Если бы я тогда хотел отобразить только первое значение столбца 2, код будет s = df['Column2'].str[:1].map(df['Column3'].value_counts()).fillna(0) ?