Python - Как сделать условный подсчет строк на основе различных столбцов? - PullRequest
1 голос
/ 17 февраля 2020

Я хочу создать Python фрейм данных, который подсчитывает, сколько раз типы C или P встречаются для каждой даты в каждом образец. C и P являются подмножествами F, означающими, что всякий раз, когда Type равен F , я могу посчитать количество строк с одинаковым значением Sample и то же самое Дата значение.
Я не могу жестко закодировать условия, так как фактический набор данных намного больше, чем образец. Это означает, что мне нужно основывать свои условия на значениях в наборе данных, где Тип равен F .
Вот пример моего набора данных, df_Data ( намного больше):

Пример | Тип | Дата | Strike
A | F | 1 июня 2020 |
A | C | 1 июня 2020 | 5
A | P | 1 июня 2020 | 2,5
А | F | 1 De c 2020 |
A | P | 1 De c 2020 | 3
А | P | 1 De c 2020 | 3,5
А | P | 1 De c 2020 | 4
B | F | 1 июня 2020 |
B | C | 1 июня 2020 | 2,5
B | C | 1 июня 2020 | 3
B | C | 1 июня 2020 | 4
B | F | 1 De c 2020 |
B | C | 1 De c 2020 | 2
B | C | 1 De c 2020 | 4
B | P | 1 De c 2020 | 2
B | P | 1 De c 2020 | 4

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

Пример | Тип | Дата | Count

=======================

A | F | 1 Jun 2020 |2
A | F | 1 Dec 2020 |3
B | F | 1 Jun 2020 |3
B | F | 1 Dec 2020 |4  

В Excel я бы использовал функцию CountIfs:
IF Type = "F", затем счетчики (столбец выборки, значение выборки, столбец даты, значение даты, столбец типа, "<> F")

Пожалуйста, помогите (извинения за плохое форматирование таблицы).

Ответы [ 3 ]

2 голосов
/ 17 февраля 2020

Я предлагаю следующий код:

import pandas as pd
df = pd.read_csv('sample.csv')
df['Type']=df['Type'].apply(lambda x: 'F' if x == 'P' or 'C' else '')
adf = df.groupby(['Sample', 'Type', 'Dat`enter code here`e'],as_index=False).agg({'Strike':['count']})

Этот код читает sample.csv в кадре данных. Затем вы выполняете лямбда-запрос к столбцу Type. Окончательный результат в adf.

2 голосов
/ 17 февраля 2020

Мне удалось получить требуемый вывод на основе логики c, предоставленной @ Ume sh Шарма.
Из исходного кадра данных, df , я создал кадр данных без какого-либо из F строк.

df_no_F = df[df['Type'] != "F"]  

Затем я использую groupby и count, чтобы определить количество строк для каждой комбинации Sample и Date .

df_count = df_no_F.groupby(['Sample' , 'Date'], as_index=False).count()
1 голос
/ 17 февраля 2020

Вот как бы я это сделал. Используйте df.loc для фильтрации до нужных типов, а затем groupby и count:)

import pandas as pd
from io import StringIO

# Getting a df in the right form
s = """Sample | Type | Date | Strike
A | F | 1 Jun 2020 |
A | C | 1 Jun 2020 | 5
A | P | 1 Jun 2020 | 2.5
A | F | 1 Dec 2020 |
A | P | 1 Dec 2020 | 3
A | P | 1 Dec 2020 | 3.5
A | P | 1 Dec 2020 | 4
B | F | 1 Jun 2020 |
B | C | 1 Jun 2020 | 2.5
B | C | 1 Jun 2020 | 3
B | C | 1 Jun 2020 | 4
B | F | 1 Dec 2020 |
B | C | 1 Dec 2020 | 2
B | C | 1 Dec 2020 | 4
B | P | 1 Dec 2020 | 2
B | P | 1 Dec 2020 | 4"""
df = pd.DataFrame(pd.read_csv(StringIO(s), sep='|'))
df.columns = [i.strip() for i in df.columns]
for col in ['Sample', 'Type', 'Date']:
    df[col] = df[col].str.strip()

# Meat and bones of this operation
new_df = df.loc[(df['Type'] == 'C') | (df['Type'] == 'P')].groupby(['Sample', 'Date'])['Strike'].count().reset_index()

# Reformat to desired output
new_df['Type'] = 'F'
new_df = new_df[df.columns].rename(columns={'Strike': 'Count'}).sort_values(by=['Sample', 'Date'], ascending=[True, False])
print(new_df)

Выход:

  Sample Type        Date  Count
1      A    F  1 Jun 2020      2
0      A    F  1 Dec 2020      3
3      B    F  1 Jun 2020      3
2      B    F  1 Dec 2020      4
...