Работа с вычитанием и индексами Pandas Dataframe - PullRequest
0 голосов
/ 27 августа 2018

У меня есть несколько текстовых файлов, с некоторыми хронологическими показателями по данным о недвижимости с течением времени.Я хотел бы импортировать эти данные в фрейм данных, а затем рассчитать новый фрейм данных, представляющий собой разницу между метрикой для конкретного города относительно среднего значения по всем городам на эту дату.Для данной даты я также хотел бы, чтобы выходные данные были равны NaN, если в отдельном городе не было данных, даже если для других городов имеется соответствующее среднее значение.

Пара проблем, с которыми я столкнулся или обеспокоен

-> Я не уверен, как лучше всего избежать ситуации, когда некоторые данные Мемфиса = «NaN», ноСреднее количество городов было 17, поэтому Мемфис - Среднее = -17.Мое желаемое поведение для Мемфиса (NaN) минус Среднее (17) = NaN.

-> Мой порядок столбцов меняется на алфавитный при вычитании моего среднего из отдельных городов, и я не знаюЗачем.Хотя я проверил вручную, я обеспокоен, что я делаю что-то не так с точки зрения индексации, так что я могу вычитать выровненные столбцы или строки, не зная об этом.

-> Я извлекаю некоторые текстовые данные(строка «Запись» и название «Город») из моего исходного набора данных и конкатенация его обратно в окончательный относительный город.Это кажется немного неэффективным, и я обеспокоен тем, что это может добавить риск индексации.

import glob
import pandas as pd

df = pd.concat([pd.read_csv(f, na_values = ['#VALUE!', '#DIV/0!'], keep_default_na = True) for f in glob.glob('city Text Files/*.txt')], ignore_index = True)

df_headers = df.loc[:,['Record','City']]
df_average = df.groupby(['Date'], as_index=False).mean()

df_rel_cities_wip = (df.set_index('Date')-df_average.set_index('Date').reindex(df.Date)).reset_index()
df_rel_cities_wip = df_rel_cities_wip.drop(['Record','City'], axis = 1) #these otherwise stay behind as blank columns because they're strings
df_rel_cities_wip = df_rel_cities_wip.round(6) #Gets rid of floating point almost-zeros
df_rel_cities = pd.concat([df_headers, df_rel_cities_wip], axis=1, sort=False) #Bolts city names and alpha record numbers back to the relative dataset

РЕДАКТИРОВАТЬ - ДОБАВЛЕНИЕ НЕКОТОРЫХ ОБРАЗЦОВ ДАННЫХ ДЛЯ ИЛЛЮСТРАЦИИ Первый кадр данных (df) будет исходными записями.По разным причинам, 3 января, для Мемфиса может оказаться нереальным $ / sqft или число дней в рынке (DOM), доступных для Мемфиса.

Record  City    Date        $/SQFT  DOM
M12 Memphis 01/01/2018  100 18
M13 Memphis 01/02/2018  112 73
M14 Memphis 01/03/2018  NaN NaN
D73 Dallas  01/01/2018  300 36
D74 Dallas  01/02/2018  320 53
D75 Dallas  01/03/2018  325 43
A19 Atlanta 01/01/2018  255 11
A20 Atlanta 01/03/2018  263 18

Средняя метрика за каждый день для всех этих городов выглядит следующим образом(df_average)

Date        $/SQFT  DOM
01/01/2018  218.3   21.7
01/02/2018  216.0   63.0
01/03/2018  294.0   30.5

И мой последний фрейм данных (df_rel_cities) будет показывать разницу между «средним по городу» на каждую дату и фактическим.Обратите внимание, что M14 Memphis - это NaN, чтобы начать, поэтому желаемый результат - увидеть NaN как разницу по сравнению с отраслью, учитывая, что у Мемфиса в тот день были проблемные данные.Когда я запускаю свой код выше, я нахожу его в алфавитном порядке и порядок столбцов.

Record  City    Date        $/SQFT  DOM
M12 Memphis 01/01/2018  -118.3  -3.7
M13 Memphis 01/02/2018  -104.0  10.0
M14 Memphis 01/03/2018  NaN NaN
D73 Dallas  01/01/2018  81.7    14.3
D74 Dallas  01/02/2018  104.0   -10.0
D75 Dallas  01/03/2018  31.0    12.5
A19 Atlanta 01/01/2018  36.7    -10.7
A20 Atlanta 01/03/2018  -31.0   -12.5

1 Ответ

0 голосов
/ 27 августа 2018

Мне кажется нужно:

df = pd.concat([pd.read_csv(f, na_values = ['#VALUE!', '#DIV/0!'], keep_default_na = True) 
                for f in glob.glob('city Text Files/*.txt')])

#get only numeric columns
cols = df.select_dtypes(np.number).columns

#create DataFrame with same size as original with means
df_average = df.groupby('Date')[cols].transform('mean')
print (df_average)
       $/SQFT        DOM
0  218.333333  21.666667
1  216.000000  63.000000
2  294.000000  30.500000
3  218.333333  21.666667
4  216.000000  63.000000
5  294.000000  30.500000
6  218.333333  21.666667
7  294.000000  30.500000

#substract only numeric columns 
df[cols] = (df[cols] - df_average ).round(1)
print (df)
  Record     City        Date  $/SQFT   DOM
0    M12  Memphis  01/01/2018  -118.3  -3.7
1    M13  Memphis  01/02/2018  -104.0  10.0
2    M14  Memphis  01/03/2018     NaN   NaN
3    D73   Dallas  01/01/2018    81.7  14.3
4    D74   Dallas  01/02/2018   104.0 -10.0
5    D75   Dallas  01/03/2018    31.0  12.5
6    A19  Atlanta  01/01/2018    36.7 -10.7
7    A20  Atlanta  01/03/2018   -31.0 -12.5
...