#python #pandas #dataframe
#python #pandas #dataframe
Вопрос:
Я работаю над проектом, который пытается перенести функции и операции из Excel в python в pandas.
У меня есть много функций SUMIF, которые я пытаюсь воспроизвести в данных. Проблема в том, что я не думаю, что pandas имеет специально аналогичную функцию. У меня может быть выражение Excel, например:
=(SUMIFS('Sheetname'!BI$146:BI$282,'Sheetname'!$B$146:$B$282,$I1836))
Где первый аргумент — это область, которую необходимо суммировать. Вторая область — это диапазон, в котором мы проверяем соответствие критериям, а последний аргумент — это конкретное значение, которое мы ищем.
То, что я делаю прямо сейчас, — это запуск вложенного цикла, который перебирает все строки и столбцы и проверяет, что первая итерация находит совпадающие строки, в то время как внутренний цикл находит совпадающие столбцы. Затем значения суммируются и вводятся в функцию pandas.
Что-то вроде:
table_dict_temp — это таблица, в которую я заполняю значения, в table_temp — это таблица, на которую нужно ссылаться
for i in range(len(table_dict_temp)):
cog_loss = table_temp.loc[table_temp[COLUMN OF COMPARISON]==table_dict_temp[COLUMN OF COMPARISON][i]]
for j in range(10, len(table_dict_temp.columns)):
cog_loss_temp = cog_loss[table_dict_temp.columns[j]].sum()
table_dict_temp.iloc[i,j]=cog_loss_temp
Проблема, с которой я сталкиваюсь, заключается в том, что это, похоже, непитонический способ сделать это, и это также занимает много времени. Буду признателен за любые советы о том, как я могу написать функцию быстрее!
Комментарии:
1. Я не думаю, что в целом отличная идея пытаться копировать функции Excel в Python, особенно с использованием итеративного решения, как в вашем примере. Это самый медленный метод работы с массивами в Python. Вместо этого лучше разработать новое решение, используя векторизованные функции из Pandas или Numpy.
2. Привет, @Arpit-bajpai. Вам следует избегать использования
for i in range(len(iterable))
just usefor element in iterable
. Кроме того, нельзя использовать циклы и Pandas вместе. Предоставьте некоторые примеры данных, и мы сможем их обработать.3. Попробуйте использовать что-то вроде библиотеки Kola 2, которая преобразует функции Excel в Python pypi.org/project/koala2
Ответ №1:
Данные примера Excel:
https://support.microsoft.com/en-us/office/sumifs-function-c9e748f5-7ea7-455d-9406-611cebce642b
Quantity Sold Product Salesperson
5 Apples Tom
4 Apples Sarah
15 Artichokes Tom
3 Artichokes Sarah
22 Bananas Tom
12 Bananas Sarah
10 Carrots Tom
33 Carrots Sarah
Description
=SUMIFS(A2:A9, B2:B9, "=A*", C2:C9, "Tom")
Adds the number of products that begin with A and were sold by Tom.
It uses the wildcard character * in Criteria1, "=A*" to look for matching product names in Criteria_range1 B2:B9,
and looks for the name "Tom" in Criteria_range2 C2:C9.
It then adds the numbers in Sum_range A2:A9 that meet both conditions.
The result is 20.
=SUMIFS(A2:A9, B2:B9, "<>Bananas", C2:C9, "Tom")
Adds the number of products that aren’t bananas and are sold by Tom.
It excludes bananas by using <> in the Criteria1, "<>Bananas",
and looks for the name "Tom" in Criteria_range2 C2:C9.
It then adds the numbers in Sum_range A2:A9 that meet both conditions.
The result is 30.
решение pythonic:
import io
import pandas as pd
data_str = '''
Quantity Sold Product Salesperson
5 Apples Tom
4 Apples Sarah
15 Artichokes Tom
3 Artichokes Sarah
22 Bananas Tom
12 Bananas Sarah
10 Carrots Tom
33 Carrots Sarah
'''.strip()
df = pd.read_csv(io.StringIO(data_str), sep='t')
# =SUMIFS(A2:A9, B2:B9, "=A*", C2:C9, "Tom")
cond = True
cond amp;= df['Product'].str.startswith('A')
cond amp;= df['Salesperson'] == 'Tom'
df.loc[cond, 'Quantity Sold'].sum()
# =SUMIFS(A2:A9, B2:B9, "<>Bananas", C2:C9, "Tom")
cond = True
cond amp;= df['Product'] != 'Bananas'
cond amp;= df['Salesperson'] == 'Tom'
df.loc[cond, 'Quantity Sold'].sum()