flask와 pandas를 연결해봅시다.
3 분 소요
flask와 pd.DataFrame 연동하기
- 저는 데이터는 일단 엑셀 파일로 들어온다고 가정합니다. 따라서
pandas
를 이용해서 엑셀을 dataframe로 변환해서 처리하는 것이 반드시 필요하죠.
- flask에서 dataframe를 연동하는 것에 문제가 없는지 확인해봅니다.
make and read excel file
from flask import Flask
app = Flask(__name__, static_url_path='/static')
@app.route('/pandas')
def make_read_excel():
## 반드시 static에 있지 않아도 읽을 수는 있음.
## 현재 파일과 읽으려는 파일이 같은 경로에 있기 때문에 아래와 같은 방식으로 읽을 수도 있음.
import pandas as pd
import numpy as np
## make excel file
writer = pd.ExcelWriter('static/excel_for_flask.xlsx')
df = pd.DataFrame({"col_{}".format(i):list(np.random.randint(0, 100, 100)) for i in range(0, 8)})
df.to_excel(writer, 'sheet1')
writer.save()
## read excel file
df = pd.read_excel('static/excel_for_flask.xlsx')
## 아주 다행히도, dataframe을 html 문서로 바로 변환해주는 형식이 있습니다.
return df.to_html()
if __name__ == '__main__':
# threaded=True 로 넘기면 multiple plot이 가능해짐
app.run(debug=True, threaded=True)
|
col_0 |
col_1 |
col_2 |
col_3 |
col_4 |
col_5 |
col_6 |
col_7 |
0 |
2 |
7 |
4 |
0 |
0 |
1 |
7 |
0 |
1 |
3 |
9 |
1 |
9 |
7 |
1 |
7 |
8 |
2 |
8 |
7 |
6 |
4 |
9 |
7 |
9 |
5 |
styling
- dataframe을 html로 변환하는 과정에서 뭐 적당히 나쁘지 않게 나오기는 했는데, 썩 마음에 들지는 않습니다.
df.to_html()
로 값만 받은 다음에 css를 embed하여 처리하는 것이 더 낫지 않을까 싶기는 합니다만.
pandas
에서 직접 스타일링을 하여 넘겨줄 수도 있습니다.
- 테이블 간의 간격이나, 문제가 되는 포인트를 색깔로 구분할 수 있게 보여주면 훨씬 좋을 것 같아요.
@app.route('/pandas')
def make_read_excel():
## 반드시 static에 있지 않아도 읽을 수는 있음.
## 현재 파일과 읽으려는 파일이 같은 경로에 있기 때문에 아래와 같은 방식으로 읽을 수도 있음.
import pandas as pd
import numpy as np
## make excel file
writer = pd.ExcelWriter('static/excel_for_flask.xlsx')
df = pd.DataFrame({"col_{}".format(i):list(np.random.randint(0, 10, 10)) for i in range(0, 8)})
df.to_excel(writer, 'sheet1')
writer.save()
## read excel file
df = pd.read_excel('static/excel_for_flask.xlsx')
## styling을 해봅시다.
## cell의 값을 기준으로 스타일링하기
## 아래 함수를 사용하여 style.applymap(color_extreme) 로 넘겨주면 적용됨
def color_extreme(val):
if val==0:
return 'color: {}'.format('red')
elif val==9:
return 'color: {}'.format('blue')
else:
return 'color: {}'.format('black')
df_with_style = df.style.applymap(color_extreme)
## data의 format을 변경할 때
df_with_style = df_with_style.format("{:.2f}")
## 전체 프로퍼티를 변화하고 싶을 때
df_with_style.set_properties(**{
'background-color':'white',
'border':'1px solid black',
'font-size': '20px',
})
## 요소 별로 변화시키고 싶을 때
styles = [
{'selector':'td',
'props':[('text-align', 'center'), ('font-size', '20px'), ('height', '50px'), ('width', '100px')
]},
{'selector':'tr', 'props':[('font-size', '30px')]}
]
df_with_style = df_with_style.set_table_styles(styles)
## matplotlib의 colormap을 이용하여 cell의 값 정도를 표시하고 싶을 때
df_with_style = df_with_style.background_gradient(cmap='Reds')
#df_with_style = df_with_style.set_table_styles(styles)
## html로 렌더링해주어야 함
return df_with_style.render()
|
col_0 |
col_1 |
col_2 |
col_3 |
col_4 |
col_5 |
col_6 |
col_7 |
0 |
2.00 |
8.00 |
1.00 |
3.00 |
3.00 |
3.00 |
1.00 |
5.00 |
1 |
0.00 |
9.00 |
2.00 |
6.00 |
5.00 |
8.00 |
7.00 |
5.00 |
2 |
9.00 |
2.00 |
3.00 |
2.00 |
5.00 |
0.00 |
2.00 |
2.00 |
wrap-up
- 그냥 css로 적용하는 것이 좋을 수도 있겠지만, 값에 따라서 엑셀처럼 다른 형식으로 보여주는 것들은 좋은 것 같아요.
reference
raw code
from flask import Flask
app = Flask(__name__, static_url_path='/static')
@app.route('/pandas')
def make_read_excel():
## 반드시 static에 있지 않아도 읽을 수는 있음.
## 현재 파일과 읽으려는 파일이 같은 경로에 있기 때문에 아래와 같은 방식으로 읽을 수도 있음.
import pandas as pd
import numpy as np
## make excel file
writer = pd.ExcelWriter('static/excel_for_flask.xlsx')
df = pd.DataFrame({"col_{}".format(i):list(np.random.randint(0, 10, 3)) for i in range(0, 8)})
df.to_excel(writer, 'sheet1')
writer.save()
## read excel file
df = pd.read_excel('static/excel_for_flask.xlsx')
return df.to_html()
## styling을 해봅시다.
## cell의 값을 기준으로 스타일링하기
## 아래 함수를 사용하여 style.applymap(color_extreme) 로 넘겨주면 적용됨
def color_extreme(val):
if val==0:
return 'color: {}'.format('red')
elif val==9:
return 'color: {}'.format('blue')
else:
return 'color: {}'.format('black')
df_with_style = df.style.applymap(color_extreme)
## data의 format을 변경할 때
df_with_style = df_with_style.format("{:.2f}")
## 전체 프로퍼티를 변화하고 싶을 때
df_with_style.set_properties(**{
'background-color':'white',
'border':'1px solid black',
'font-size': '20px',
})
## 요소 별로 변화시키고 싶을 때
styles = [
{'selector':'td',
'props':[('text-align', 'center'), ('font-size', '20px'), ('height', '50px'), ('width', '100px')
]},
{'selector':'tr', 'props':[('font-size', '30px')]}
]
df_with_style = df_with_style.set_table_styles(styles)
## matplotlib의 colormap을 이용하여 cell의 값 정도를 표시하고 싶을 때
df_with_style = df_with_style.background_gradient(cmap='Reds')
#df_with_style = df_with_style.set_table_styles(styles)
## html로 렌더링해주어야 함
return df_with_style.render()
if __name__ == '__main__':
# threaded=True 로 넘기면 multiple plot이 가능해짐
app.run(debug=True, threaded=True)
댓글남기기