2016-01-19 3 views
1

У меня есть дата-карта с временными и категориальными данными.Python and Pandas - Определение срока просрочки счета

╔═════════════════════════════════════════════╗ 
    ║ Name  BillDate    Bill Status ║ 
    ╠═════════════════════════════════════════════╣ 
    ║ Company A 2015-07-22 15:51:00 Paid  ║ 
    ║ Company B 2015-01-31 12:01:00 Unpaid  ║ 
    ║ Company C 2016-01-12 00:00:00 Unpaid  ║ 
    ╚═════════════════════════════════════════════╝ 

Я пытаюсь добавить еще одну колонку, говорящую мне, если счет просрочен на основе двух факторов. Первым фактором является то, что текущая дата - BillDate + 180 дней или более, а вторая - статус счета.

Я, вероятно, плотно о том, как это сделать. Мое мышление, чтобы сделать следующее:

billpayperiod = timedelta(days = 180) 
    currentdate = datetime.now() 
    df['Bill Due Date'] = df['BillDate'].apply(lambda x: x + billpayperiod) 

Затем создать некоторую функцию, которая будет проверять, чтобы увидеть, если

currendate > Bill Due Date and Bill Status = unpaid. 
If True = Overdue 
If False = No Due, 
If Bill Status = paid, then Paid. 

Я ценю ваши мысли по: 1. Имеет ли этот метод имеет смысл и 2. Помогите создать функцию, которая выполняет проверку

Поскольку я гораздо лучше первенствует, это то, что я хотел бы сделать с помощью этого:

Create the Bill Date + 180 column (name it DueDate 
    Set a cell = currentdate 
    Create a new column: formula IF(BillStatus="Paid","Paid",IF(AND(BillStatus="Unpaid",currentdate>DueDate),"Overdue","Not Overdue"))  
+0

показать нам код для создания dataframe. – NinjaGaiden

+0

Я на самом деле вытаскиваю данные из excel, любых советов или праймеров о том, как создать DataFrame, похожую на то, что выше? – DataNoob

+0

ваше второе требование не имеет смысла, у вас есть условие, которое затем установит просрочку еще не причитающуюся, но затем вы снова используете одно и то же условие, чтобы сказать, что оно выплачено ??? – EdChum

ответ

1

IIUC это будет делать то, что вы хотите:

In [21]: 
df[(((df['BillDate'] - dt.datetime.now()).dt.days).abs() > 180) & (df['Bill Status'] == 'Unpaid')] 

Out[21]: 
     Name   BillDate Bill Status 
1 Company B 2015-01-31 12:01:00  Unpaid 

Мы можем назвать dt.days на timedeltas и сравнить абсолютные значения:

In [25]: 
(df['BillDate'] - dt.datetime.now()).dt.days 

Out[25]: 
0 -182 
1 -354 
2  -8 
Name: BillDate, dtype: int64 

In [24]: 
(df['BillDate'] - dt.datetime.now()).dt.days 
((df['BillDate'] - dt.datetime.now()).dt.days).abs() 

Out[24]: 
0 182 
1 354 
2  8 
Name: BillDate, dtype: int64 

EDIT

Для установки нового статусы, вы можете определить пару масок и использовать np.where:

In [29]: 
import pandas as pd 
import numpy as np 
import datetime as dt 
overdue = (((df['BillDate'] - dt.datetime.now()).dt.days).abs() > 180) & (df['Bill Status'] == 'Unpaid') 
paid = (df['Bill Status'] == 'Paid') 
df['new status'] = np.where(paid, 'paid', np.where(overdue, 'overdue', 'no due')) 
df 
​ 
Out[29]: 
     Name   BillDate Bill Status new status 
0 Company A 2015-07-22 15:51:00  Paid  paid 
1 Company B 2015-01-31 12:01:00  Unpaid overdue 
2 Company C 2016-01-12 00:00:00  Unpaid  no due 
+0

Что я пытаюсь сделать, сделайте что-то вроде этого df [(((df ['BillDate'] - dt.datetime.now()). Dt.days) .abs()> 180) & (df ['Status Status]] ==' Unpaid ') Создайте строку из «Оплаченных», «Просроченных» или «Не погашенных» на основе указанных факторов. Мысли? – DataNoob

+0

Спасибо за редактирование. Извинения за мой нообесс, но я получаю сообщение об ошибке при попытке запустить код. Моя ошибка имени «дту» не определен Я ввожу панда как э.р., и от даты и время импорта DateTime, timedelta Есть ли что-нибудь еще мне нужно импортировать, чтобы получить код для работы? – DataNoob

+0

try 'import datetime as dt' – EdChum

1

Вы можете легко добавить колонку в панд с помощью

#create columns 'newStatus' and set default to No due 
df['newStatus'] = 'No Due' 

Затем вы можете использовать .loc и индексы из приведенных выше ответов, чтобы установить его конкретные значения

df.loc[indices,column] = value 

, например, :

#create indices for unpaid bills, and for bills that are due 
iUnpaid = df['Bill Status']=='Unpaid' 
iDue = (((df['BillDate'] - dt.datetime.now()).dt.days).abs() > 180) 

#update corresponding values 
df.loc[iUnpaid & iDue,'newStatus'] = 'Due' 
df.loc[iUnpaid & ~iDue,'newStatus'] = 'No Due' 
Смежные вопросы