Как бухгалтер, вы можете столкнуться со случаями, когда закон требует, чтобы вы разбили все бухгалтерские документы, чтобы каждая проводка по дебету соответствовала ровно одной проводке по кредиту, и наоборот.
Что делать, если ваша бухгалтерская система не поддерживает вас в этом? Разбивка большой электронной таблицы GL вручную — очень скучная и трудоемкая задача.
Сегодня я представлю метод разбивки бухгалтерских документов с помощью Python и Pandas.
Pandas – это быстрый, мощный, гибкий и простой в использовании инструмент для анализа и обработки данных с открытым исходным кодом, созданный на основе языка программирования Python. Если вы не знаете о Pandas, посетите веб-сайт:
Pandas предоставляет отличную документацию, так что вы можете быстро с ней ознакомиться. В роли бухгалтера я активно использую Pandas для автоматизации повседневных задач.
Учитывая, что у нас есть электронная таблица GL следующим образом:
Мой файл GL хранится по пути: «D:/GL.xlsx»
- Начнем с использования Pandas для чтения файла GL.
# Read the excel file to get a Pandas dataframe df=pd.read_excel("D:/GL.xlsx")
Визуализация фрейма данных при просмотре с помощью Jupyter Notebook почти аналогична электронной таблице Excel.
Желаемый результат:
2. Напишите 04 функции для управления данными
# Check if there is any values different from 0 or empty def check_dict_values(dict_): for i in dict_.values(): if i!=0: return False return True # Transform a original data frame to dictionary # Return three values: # debit_account_dict : Dictionary , key is account number, value is amount # credit_account_dict : Dictionary , key is account number, value is amuont # The returned values are inputs for find_match_outer() function def get_dict_from_data_frame(df): # Create two data frames by filter 'Debit/Credit' column # get rows that sastify the condition that columns 'Debit/Credit' value is 'Debit' df_debit= df.loc[df['Debit/Credit']=='Debit'] # get rows that sastify the condition that columns 'Debit/Credit' value is 'Credit' df_credit= df.loc[df['Debit/Credit']=='Credit'] # Use zip() built-in function to create a zip object from two Data Frame columns # Use dict() built-in function to convert zip object to a Dictonary debit_account_dict= dict(zip(df_debit['Account_number'], df_debit['Amount'])) credit_account_dict= dict(zip(df_credit['Account_number'], df_credit['Amount'])) return debit_account_dict,credit_account_dict,df['Document_number'].to_list()[0] # This function will return the transformed dataframe for each docmument number # Parameters are output of get_dict_from_data_frame() function def find_match_outer(debit_account_dict, credit_account_dict, document_number): # I use nested function since I want three below variables are in local scope only # These lists will be modified by the inner function # We will use these lists to create a dictionary # We will use the dictionary to create a data frame debit_account_list=[] credit_account_list=[] value_list=[] # Inner function : def find_match_inner(debit_account_dict, credit_account_dict): # The function will loop until debit_account_dict or check_dict_values is empty while True: # if map values are zero or empty -> work done if(check_dict_values(debit_account_dict) or check_dict_values(credit_account_dict)): return # Find the key of min value of debit min_debit_key= min(debit_account_dict, key = lambda k: debit_account_dict[k]) # Find min debit value min_debit_value= debit_account_dict[min_debit_key] # Find the key of min value of credit min_credit_key = min(credit_account_dict, key = lambda k: credit_account_dict[k]) # Find min credit value min_credit_value= credit_account_dict[min_credit_key] # Add keys of min values to lists debit_account_list.append(min_debit_key) credit_account_list.append(min_credit_key) # Compare if(min_credit_value <= min_debit_value): print("min is credit: ",min_credit_value) value_list.append(min_credit_value) # Decrease value of min_debit_key in the debit_account_dict by min_credit_value debit_account_dict[min_debit_key]-=min_credit_value # Remove min_credit_key from credit_account_dict credit_account_dict.pop(min_credit_key) else: print("min is debit: ",min_debit_value) value_list.append(min_debit_value) # Decrease value of min_debit_key in the debit_account_dict by min_debit_value credit_account_dict[min_credit_key]-=min_debit_value # Remove min_credit_key from credit_account_dict debit_account_dict.pop(min_debit_key) # Call inner function find_match_inner(debit_account_dict, credit_account_dict) # Create a data frame from dictionary, the dictionary is created from 03 lists that I have defined df=pd.DataFrame({'Debit_account': debit_account_list, 'Credit_account': credit_account_list,'Value':value_list}) df['Document_number']=document_number # Re-arrange columns position df= df.loc[:,['Document_number','Debit_account','Credit_account','Value']] return df # This function will take the original data frame read from spread sheet as input # Return the final result def transform(df): # Define an empty list to hold transformed dataframes df_list_transformed=[] # Use df.groupby('Document_number') to get a pandas.core.groupby.generic.DataFrameGroupBy object # Unpack DataFrameGroupBy object and use Python list comprehension syntax to make a list of DataFrames df_list_org = [df for _, df in df.groupby('Document_number')] # Loop through df_list_org for df in df_list_org: # Transfrom each data frame debit_account_dict, credit_account_dict, document_number=get_dict_from_data_frame(df) df_transformed= find_match_outer(debit_account_dict, credit_account_dict, document_number) # Add transformed dataframes to df_list_transformed df_list_transformed.append(df_transformed) # Concatenate transformed dataframes df_concat= pd.concat(df_list_transformed) # Reset index df_concat.reset_index(inplace=True,drop=True) return df_concat
3. Проверим, как работает наша программа
# Read the excel file to get a Pandas dataframe df=pd.read_excel("D:/GL.xlsx") # Transform data using written functions df_transformed=transform(df)
4. Результат ожидаемый, в каждой строке мы видим дебетовый счет и соответствующий ему кредитный счет.
Спасибо за прочтение, надеюсь, что моя статья окажется для вас полезной!
Я также являюсь предпринимателем, начинающим бизнес в области вышивки. Пожалуйста, посетите мой веб-сайт, если вы заинтересованы в вышивальных изделиях: http://anhoahome.com