中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

pandas.DataFrame的pivot()和unstack()實現行轉列

發布時間:2020-09-24 09:41:20 來源:腳本之家 閱讀:328 作者:Leohahah 欄目:開發技術

示例:有如下表需要進行行轉列:

pandas.DataFrame的pivot()和unstack()實現行轉列

代碼如下:

# -*- coding:utf-8 -*-

import pandas as pd

import MySQLdb

from warnings import filterwarnings

# 由于create table if not exists總會拋出warning,因此使用filterwarnings消除

filterwarnings('ignore', category = MySQLdb.Warning)

from sqlalchemy import create_engine

import sys

if sys.version_info.major<3:

 reload(sys)

 sys.setdefaultencoding("utf-8")

 # 此腳本適用于python2和python3

host,port,user,passwd,db,charset="192.168.1.193",3306,"leo","mysql","test","utf8"

 

def get_df():

 global host,port,user,passwd,db,charset

 conn_config={"host":host, "port":port, "user":user, "passwd":passwd, "db":db,"charset":charset}

 conn = MySQLdb.connect(**conn_config)

 result_df=pd.read_sql('select UserName,Subject,Score from TEST',conn)

 return result_df

 

def pivot(result_df):

 df_pivoted_init=result_df.pivot('UserName','Subject','Score')

 df_pivoted = df_pivoted_init.reset_index() # 將行索引也作為DataFrame值的一部分,以方便存儲數據庫

 return df_pivoted_init,df_pivoted

 # 返回的兩個DataFrame,一個是以姓名作index的,一個是以數字序列作index,前者用于unpivot,后者用于save_to_mysql

 

def unpivot(df_pivoted_init):

 # unpivot需要進行df_pivoted_init二維表格的行、列索引遍歷,需要拼SQL因此不能使用save_to_mysql存數據,這里使用SQL和MySQLdb接口存

 insert_sql="insert into test_unpivot(UserName,Subject,Score) values "

 # 處理值為NaN的情況

 df_pivoted_init=df_pivoted_init.fillna(0)

 for col in df_pivoted_init.columns:

  for index in df_pivoted_init.index:

   value=df_pivoted_init.at[index,col]

   if value!=0:

    insert_sql=insert_sql+"('%s','%s',%s)" %(index,col,value)+','

 insert_sql = insert_sql.strip(',')

 global host, port, user, passwd, db, charset

 conn_config = {"host": host, "port": port, "user": user, "passwd": passwd, "db": db, "charset": charset}

 conn = MySQLdb.connect(**conn_config)

 cur=conn.cursor()

 cur.execute("create table if not exists test_unpivot like TEST")

 cur.execute(insert_sql)

 conn.commit()

 conn.close()

 

def save_to_mysql(df_pivoted,tablename):

 global host, port, user, passwd, db, charset

 """

 只有使用sqllite時才能指定con=connection實例,其他數據庫需要使用sqlalchemy生成engine,engine的定義可以添加?來設置字符集和其他屬性

 """

 conn="mysql://%s:%s@%s:%d/%s?charset=%s" %(user,passwd,host,port,db,charset)

 mysql_engine = create_engine(conn)

 df_pivoted.to_sql(name=tablename, con=mysql_engine, if_exists='replace', index=False)

 

# 從TEST表讀取源數據至DataFrame結構

result_df=get_df()

# 將源數據行轉列為二維表格形式

df_pivoted_init,df_pivoted=pivot(result_df)

# 將二維表格形式的數據存到新表test中

save_to_mysql(df_pivoted,'test')

# 將被行轉列的數據unpivot,存入test_unpivot表中

unpivot(df_pivoted_init)

結果如下:

pandas.DataFrame的pivot()和unstack()實現行轉列

關于Pandas DataFrame類自帶的pivot方法:

DataFrame.pivot(index=None, columns=None, values=None):

Return reshaped DataFrame organized by given index / column values.

這里只有3個參數,是因為pivot之后的結果一定是二維表格,只需要行列及其對應的值,而且也因為是二維表格,unpivot之后is_pass列是肯定會丟失的,因此一開始我就沒查這個列。

補充說明:

在學習到Pandas的層次化索引部分時發現了2個很有意思的函數,也可以進行行列互轉,其用法如下:(很久之后我才意識到,pivot只是封裝了unstack的一個快捷方式而已,其本質上還是先用set_index建立層次化索引,然后用unstack進行重塑,就像我在下面示例做的操作)

# -*- coding:utf-8 -*-

import pandas as pd

import MySQLdb

from warnings import filterwarnings

# 由于create table if not exists總會拋出warning,因此使用filterwarnings消除

filterwarnings('ignore', category = MySQLdb.Warning)

from sqlalchemy import create_engine

import sys

if sys.version_info.major<3:

 reload(sys)

 sys.setdefaultencoding("utf-8")

 # 此腳本適用于python2和python3

host,port,user,passwd,db,charset="192.168.1.193",3306,"leo","mysql","test","utf8"

 

def get_df():

 global host,port,user,passwd,db,charset

 conn_config={"host":host, "port":port, "user":user, "passwd":passwd, "db":db,"charset":charset}

 conn = MySQLdb.connect(**conn_config)

 result_df=pd.read_sql('select UserName,Subject,Score from TEST',conn)

 return result_df

 

def pivot(result_df):

 df_pivoted_init=result_df.pivot('UserName','Subject','Score')

 df_pivoted = df_pivoted_init.reset_index() # 將行索引也作為DataFrame值的一部分,以方便存儲數據庫

 return df_pivoted_init,df_pivoted

 # 返回的兩個DataFrame,一個是以姓名作index的,一個是以數字序列作index,前者用于unpivot,后者用于save_to_mysql

 

def unpivot(df_pivoted_init):

 # unpivot需要進行df_pivoted_init二維表格的行、列索引遍歷,需要拼SQL因此不能使用save_to_mysql存數據,這里使用SQL和MySQLdb接口存

 insert_sql="insert into test_unpivot(UserName,Subject,Score) values "

 # 處理值為NaN的情況

 df_pivoted_init=df_pivoted_init.fillna(0)

 for col in df_pivoted_init.columns:

  for index in df_pivoted_init.index:

   value=df_pivoted_init.at[index,col]

   if value!=0:

    insert_sql=insert_sql+"('%s','%s',%s)" %(index,col,value)+','

 insert_sql = insert_sql.strip(',')

 global host, port, user, passwd, db, charset

 conn_config = {"host": host, "port": port, "user": user, "passwd": passwd, "db": db, "charset": charset}

 conn = MySQLdb.connect(**conn_config)

 cur=conn.cursor()

 cur.execute("create table if not exists test_unpivot like TEST")

 cur.execute(insert_sql)

 conn.commit()

 conn.close()

 

def save_to_mysql(df_pivoted,tablename):

 global host, port, user, passwd, db, charset

 """

 只有使用sqllite時才能指定con=connection實例,其他數據庫需要使用sqlalchemy生成engine,engine的定義可以添加?來設置字符集和其他屬性

 """

 conn="mysql://%s:%s@%s:%d/%s?charset=%s" %(user,passwd,host,port,db,charset)

 mysql_engine = create_engine(conn)

 df_pivoted.to_sql(name=tablename, con=mysql_engine, if_exists='replace', index=False)

 

# 從TEST表讀取源數據至DataFrame結構

result_df=get_df()

# 將源數據行轉列為二維表格形式

df_pivoted_init,df_pivoted=pivot(result_df)

# 將二維表格形式的數據存到新表test中

save_to_mysql(df_pivoted,'test')

# 將被行轉列的數據unpivot,存入test_unpivot表中

unpivot(df_pivoted_init)

以上利用了Pandas的層次化索引,實際上這也是層次化索引一個主要的用途,結合本例我們可以把代碼改成如下:

result_df=pd.read_sql('select UserName,Subject,Score from TEST',conn)

# 在從數據庫中獲取的數據格式是這樣的:

    UserName Subject Score

0    張三   語文  80.0

1    張三   數學  90.0

2    張三   英語  70.0

3    張三   生物  85.0

4    李四   語文  80.0

5    李四   數學  92.0

6    李四   英語  76.0

7    王五   語文  60.0

8    王五   數學  82.0

9    王五   英語  96.0

10    王五   生物  78.0

# 如果要使用層次化索引,那么我們只需要把UserName和Subject列設置為層次化索引,Score為其對應的值即可,我們借用set_index()函數:

df=result_df.set_index(['UserName','Subject'])

In [112]: df.unstack()

Out[112]: 

     Score         

Subject   數學  生物  英語  語文

UserName            

張三    90.0 85.0 70.0 80.0

李四    92.0  NaN 76.0 80.0

王五    82.0 78.0 96.0 60.0

# 使用stack可以將unstack的結果轉回來,這樣就也在形式上實現了行列互轉,之后的操作基本一致了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

手游| 太白县| 澳门| 出国| 安福县| 清苑县| 尼木县| 天峨县| 商都县| 营山县| 互助| 天门市| 武陟县| 罗平县| 关岭| 垣曲县| 望都县| 大城县| 平顺县| 临邑县| 四子王旗| 大石桥市| 温州市| 丰县| 贺兰县| 四川省| 垦利县| 南京市| 平乡县| 湘乡市| 互助| 甘泉县| 花垣县| 天气| 奇台县| 冕宁县| 贡山| 九江市| 汉源县| 辉南县| 沂源县|