python3 numpy二维方法_python3中二维List数据的三种处理方法及比较

python3中二维List数据的三种处理方法及比较

标签: python 矩阵 算法

[TOC]

问题引入

这几天在处理一个棋盘状态数据,需要对棋盘状态状态是否为“同一个状态”,这里就需要对棋盘状态进行旋转,左右翻转等操作。一个棋盘总共可以旋转:0度,90度,180度,270度4种;每种旋转后还可以左右翻转2种,总共有4x2=8种状态。为了方便,需要先用python把这8种状态表示出来,于是引出了题目的问题:在python里如何对矩阵进行变化,这里的变化指旋转和左右翻转等。

这里使用的版本是python3.6

原始数据

为了简便,使用一个最简单的数据来模拟:一个2X2的棋盘用List来保存下数据

lstDat = [

[1,2],

[3,4],

]

期望的最终结果有8个,分别是这样的: 其中1,3,5,7 分别是旋转0度,90度,180度,270度; 2、4、6、8 分钟是1、3、5、7进行左右翻转得到的结果。

NO.1

1 2

3 4

No.2:

2 1

4 3

No.3:

2 4

1 3

No.4

4 2

3 1

No.5

4 3

2 1

No.6

3 4

1 2

No.7

1 3

2 4

N0.8

3 1

4 2

对于矩阵的处理有很多,但在这里只需要用到两种:

旋转90度(顺时针,逆时针都可以)

左右翻转

所以最终问题转变为如何实现对List表示的二维矩阵进行上述的两种操作。

使用列表生成式

列表生成式就是使用以下的方式来遍历生成一个新的表列: [ 变量表达式 for 变量 in 表达式 ] 当然是循环是可以嵌套的。

#---------------------------------------

## 使用列表生成式

def listGen (lstDat):

#transpose

print('-'* 30)

print ('转置矩阵:')

tp = [[row[i] for row in lstDat ] for i in range(len(lstDat[0]))]

for item in tp: print (item)

print('-'* 30)

#逆时针转90度

print ('逆时针转90度:')

rt90 = [[row[i] for row in lstDat ] for i in range(len(lstDat[0])-1,-1,-1) ]

for item in rt90: print (item)

print('-'* 30)

#顺时针转90度

print ('顺时针转90度:')

rt90 = [[lstDat[j][i] for j in range(len(lstDat)-1,-1,-1) ] for i in range(len(lstDat[0]))]

for item in rt90: print (item)

print('-'* 30)

print ('左右翻转:')

flip = [[row[i] for i in range(len(row)-1,-1,-1) ] for row in lstDat]

for item in flip: print (item)

运行结果:

---------- python36 ----------

原始数据:

[1, 2]

[3, 4]

使用列表生成器:

------------------------------

转置矩阵:

[1, 3]

[2, 4]

------------------------------

逆时针转90度:

[2, 4]

[1, 3]

------------------------------

顺时针转90度:

[3, 1]

[4, 2]

------------------------------

左右翻转:

[2, 1]

[4, 3]

输出完成 (耗时: 0 秒)

使用map + zip

使用map可以方便对矩阵进行转置,也就是把(行,列)变成 (列,行)的方式。对于旋转是有直接的方法的,但是左右翻转没有,所以需要先逆时针旋转90度,再进行转置。

def mapzip (lstDat):

print('-'* 30)

print ('转置矩阵:')

matrix = lstDat.copy()

matrix[:] = map(list,zip(*matrix))

for item in matrix: print (item)

#顺时针转90度

print ('顺时针转90度:')

matrix = lstDat.copy()

matrix[:] = map(list,zip(*matrix[::-1]))

for item in matrix: print (item)

#逆时针转90度

print ('逆时针转90度:')

matrix = lstDat.copy()

matrix[:] = map(list,zip(*matrix))

matrix[:] = matrix[::-1]

for item in matrix: print (item)

#左右翻转

print ('左右翻转:')

matrix = lstDat.copy()

matrix[:] = map(list,zip(*matrix))

matrix[:] = matrix[::-1]

matrix[:] = map(list,zip(*matrix))

for item in matrix: print (item)

运行结果:

---------- python36 ----------

原始数据:

[1, 2]

[3, 4]

==============================

使用Map+Zip:

------------------------------

转置矩阵:

[1, 3]

[2, 4]

顺时针转90度:

[3, 1]

[4, 2]

逆时针转90度:

[2, 4]

[1, 3]

左右翻转:

[2, 1]

[4, 3]

输出完成 (耗时: 0 秒)

使用numpy

最后一种方法就是直接用现成的库了,numpy提供了丰富的方法,这里只需要用到两个就够了。与map的方式相同,对于旋转是有直接的方法的,但是左右翻转没有,所以也需要先逆时针旋转90度,再进行转置。

import numpy

## 使用numpy

def usenumpy (lstDat):

nd = numpy.array(lstDat)

#逆时针转90度:

print ('逆时针转90度:')

nd1 = numpy.rot90(nd)

print (nd1)

print ('顺时针转90度:')

nd1 = numpy.rot90(nd,k = -1)

print (nd1)

print ('左右翻转:')

nd1 = numpy.rot90(nd)

nd1 = numpy.transpose(nd1)

print (nd1)

运行结果

---------- python36 ----------

原始数据:

[1, 2]

[3, 4]

==============================

使用numpy:

逆时针转90度:

[[2 4]

[1 3]]

顺时针转90度:

[[3 1]

[4 2]]

左右翻转:

[[2 1]

[4 3]]

输出完成 (耗时: 0 秒)

得到结果

研究了那么多种旋转,左右翻转的方式,最终还是为了得到8种状态,这里就用numpy方式来调用实现。

import numpy

## 输出所有状态

def getstatus (lstDat):

nd = numpy.array(lstDat)

index = 0

for i in range (4) :

index +=1

print('-'* 10 + str(index) + '-' * 10)

print (nd)

#

#print (','.join([str(y) for x in nd.tolist() for y in x]))

index +=1

print('-'* 10 + str(index) + '-' * 10)

nd2 = numpy.rot90(nd) #,k = -1,axes=(1, 0))

nd2 = numpy.transpose(nd2)

print (nd2)

#print (','.join([str(y) for x in nd2.tolist() for y in x]))

nd = numpy.rot90(nd)

运行结果:

---------- python36 ----------

原始数据:

[1, 2]

[3, 4]

==============================

输出所有状态:

----------1----------

[[1 2]

[3 4]]

----------2----------

[[2 1]

[4 3]]

----------3----------

[[2 4]

[1 3]]

----------4----------

[[4 2]

[3 1]]

----------5----------

[[4 3]

[2 1]]

----------6----------

[[3 4]

[1 2]]

----------7----------

[[3 1]

[4 2]]

----------8----------

[[1 3]

[2 4]]

输出完成 (耗时: 0 秒)

分析对比

三种思路的对比: 1.列表生成器。感觉这个比较传统,还是老思路,一个个去循环。作为练手可以用用。 2. 使用map 具有py的新思维,语句也比较简洁,建议要熟悉这种方式。 3. 使用numpy。 如果是大规模的数据,涉及到大量计算,比如ML,DL之类,还是直接用库吧。

完整源码

最后附上完整的代码: 完整源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值