Разбор файла Excel с мультииндексом в Pandas - PullRequest
0 голосов
/ 20 февраля 2019

rawdata

Каков наилучший способ анализа вышеуказанного файла Excel в кадре данных Pandas?Идея состоит в том, чтобы иметь возможность легко обновлять данные, добавлять столбцы, удалять строки.Например, для каждого источника я бы хотел оставить только output3.Затем для каждого столбца (2000, ...., 2013) разделите его на 2 с учетом условия (скажем, значение> 6000).

Ниже я попробовал следующее: сначала проанализировать и удалить ненужные строки, но это неудовлетворительно, поскольку мне пришлось переименовывать столбцы вручную.Так что это не выглядит оптимальным решением.Есть идея получше?

df = pd.read_excel("myExcel.xlsx",  skiprows=2, sheet_name='1')

cols1 = list(df.columns)
cols1 = [str(x)[:4] for x in cols1]

cols2 = list(df.iloc[0,:])
cols2 = [str(x) for x in cols2]

cols = [x + "_" + y for x,y in zip(cols1,cols2)]
df.columns = cols

df = df.drop(["Unna_nan"], axis =1).rename(columns ={'Time_Origine':'Country','Unna_Output' : 'Series','Unna_Ccy' : 'Unit','2000_nan' : '2000','2001_nan': '2001','2002_nan':'2002','2003_nan' : '2003','2004_nan': '2004','2005_nan' : '2005','2006_nan' : '2006','2007_nan' : '2007','2008_nan' : '2008','2009_nan' : '2009','2010_nan' : '2010','2011_nan': '2011','2012_nan' : '2012','2013_nan':'2013','2014_nan':'2014','2015_nan':'2015','2016_nan':'2016','2017_nan':'2017'})
df.drop(0,inplace=True)
df.drop(df.tail(1).index, inplace=True)

idx = ['Country', 'Series', 'Unit']
df = df.set_index(idx)
df = df.query('Series == "Output3"')

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019
#read first 2 rows to MultiIndex nad remove last one
df = pd.read_excel("Excel1.xlsx",  skiprows=2, header=[0,1], skipfooter=1)
print (df)

#create helper DataFrame
cols = df.columns.to_frame().reset_index(drop=True)
cols.columns=['a','b']
cols['a'] = pd.to_numeric(cols['a'], errors='ignore')
cols['b'] = cols['b'].replace('Unit.1','tmp', regex=False)
#create new column by condition
cols['c'] = np.where(cols['b'].str.startswith('Unnamed'), cols['a'], cols['b'])
print (cols)
       a                    b        c
0   Time              Country  Country
1   Time               Series   Series
2   Time                 Unit     Unit
3   Time                  tmp      tmp
4   2000   Unnamed: 4_level_1     2000
5   2001   Unnamed: 5_level_1     2001
6   2002   Unnamed: 6_level_1     2002
7   2003   Unnamed: 7_level_1     2003
8   2004   Unnamed: 8_level_1     2004
9   2005   Unnamed: 9_level_1     2005
10  2006  Unnamed: 10_level_1     2006
11  2007  Unnamed: 11_level_1     2007
12  2008  Unnamed: 12_level_1     2008
13  2009  Unnamed: 13_level_1     2009
14  2010  Unnamed: 14_level_1     2010
15  2011  Unnamed: 15_level_1     2011
16  2012  Unnamed: 16_level_1     2012
17  2013  Unnamed: 17_level_1     2013
18  2014  Unnamed: 18_level_1     2014
19  2015  Unnamed: 19_level_1     2015
20  2016  Unnamed: 20_level_1     2016
21  2017  Unnamed: 21_level_1     2017

#overwrite columns by column c
df.columns = cols['c'].tolist()
#forward filling missing values
df['Country'] = df['Country'].ffill()
df = df.drop('tmp', axis=1).set_index(['Country','Series','Unit'])
print (df)
0 голосов
/ 20 февраля 2019

Не имея такого превосходства, думаю, что-то подобное может сработать.Чтобы получить только строки из output3, вы можете использовать следующее:

df = pd.read_excel("myExcel.xlsx",  skiprows=2, sheet_name='1')
df = df.loc[df['Output'] == 'output3']

Теперь разделите каждую ячейку на 2, если значение ячейки больше 6000 с использованием панд:

def foo(bar):
    if bar > 6000:
        return bar / 2
    return bar

for col in df.columns:
    try:
        int(col)  # to check if this column is a year
        df[col] = df[col].apply(foo)
    except ValueError:
        pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...