数据结构教程¶
本教程为您提供了一个快速的介绍,关于使用 xlwings 读取和写入值时最常见的用例和默认行为。对于如何通过方法控制行为的深入文档,请参阅options
方法,查看转换器和选项.
下面的所有代码示例都依赖于以下导入:
>>> import xlwings as xw
单元格¶
默认情况下,单个单元格返回为float
, unicode
, None
或datetime
对象,具体取决于单元格是否包含数字、字符串、为空或表示日期:
>>> import datetime as dt
>>> sheet = xw.Book().sheets[0]
>>> sheet['A1'].value = 1
>>> sheet['A1'].value
1.0
>>> sheet['A2'].value = 'Hello'
>>> sheet['A2'].value
'Hello'
>>> sheet['A3'].value is None
True
>>> sheet['A4'].value = dt.datetime(2000, 1, 1)
>>> sheet['A4'].value
datetime.datetime(2000, 1, 1, 0, 0)
列表¶
一维列表:在 Excel 中表示行或列的范围将作为简单列表返回,这意味着一旦它们进入 Python,您将丢失有关方向的信息。如果这是一个问题,下一点将向您展示如何保留此信息:
>>> sheet = xw.Book().sheets[0] >>> sheet['A1'].value = [[1],[2],[3],[4],[5]] # Column orientation (nested list) >>> sheet['A1:A5'].value [1.0, 2.0, 3.0, 4.0, 5.0] >>> sheet['A1'].value = [1, 2, 3, 4, 5] >>> sheet['A1:E1'].value [1.0, 2.0, 3.0, 4.0, 5.0]
若要强制单个单元格以列表形式返回,请使用:
>>> sheet['A1'].options(ndim=1).value [1.0]
注意
要以列方向将列表写入 Excel,请使用
transpose
:sheet.range('A1').options(transpose=True).value = [1,2,3,4]
二维列表:如果需要保留行或列的方向,请在范围选项中设置
ndim
。这将使范围作为嵌套列表(“二维列表”)返回:>>> sheet['A1:A5'].options(ndim=2).value [[1.0], [2.0], [3.0], [4.0], [5.0]] >>> sheet['A1:E1'].options(ndim=2).value [[1.0, 2.0, 3.0, 4.0, 5.0]]
二维范围会自动作为嵌套列表返回。当在 Excel 中的范围内分配(嵌套)列表时,只需指定左上角单元格为目标地址即可。这个示例还使用了索引符号将值重新读回 Python:
>>> sheet['A10'].value = [['Foo 1', 'Foo 2', 'Foo 3'], [10, 20, 30]] >>> sheet.range((10,1),(11,3)).value [['Foo 1', 'Foo 2', 'Foo 3'], [10.0, 20.0, 30.0]]
注意
尝试尽量减少与 Excel 的交互次数。总是更有效率地执行sheet.range('A1').value = [[1,2],[3,4]]
而不是sheet.range('A1').value = [1, 2]
和sheet.range('A2').value = [3, 4]
.
范围扩展¶
您可以通过方法expand
或通过expand
关键字在options
方法中动态获取 Excel 范围的维度。虽然expand
返回一个扩展的范围对象,但在访问范围的值时才会评估选项。以下面的例子最好解释了两者的区别:
>>> sheet = xw.Book().sheets[0]
>>> sheet['A1'].value = [[1,2], [3,4]]
>>> range1 = sheet['A1'].expand('table') # or just .expand()
>>> range2 = sheet['A1'].options(expand='table')
>>> range1.value
[[1.0, 2.0], [3.0, 4.0]]
>>> range2.value
[[1.0, 2.0], [3.0, 4.0]]
>>> sheet['A3'].value = [5, 6]
>>> range1.value
[[1.0, 2.0], [3.0, 4.0]]
>>> range2.value
[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]
'table'
扩展为'down'
和'right'
,还有其他可用选项分别用于仅扩展列或行。
注意
使用expand()
与一个命名为左上角单元格的范围结合使用,可以为您提供 Excel 中的灵活设置:您可以移动表格并更改其大小而无需调整代码,例如通过使用类似sheet.range('NamedRange').expand().value
.
NumPy 数组¶
NumPy 数组类似于嵌套列表。但是,空单元格由nan
表示,而不是None
。如果您希望将范围作为数组读取,请设置convert=np.array
的顶部检查options
方法:
>>> import numpy as np
>>> sheet = xw.Book().sheets[0]
>>> sheet['A1'].value = np.eye(3)
>>> sheet['A1'].options(np.array, expand='table').value
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
Pandas DataFrame¶
>>> sheet = xw.Book().sheets[0]
>>> df = pd.DataFrame([[1.1, 2.2], [3.3, None]], columns=['one', 'two'])
>>> df
one two
0 1.1 2.2
1 3.3 NaN
>>> sheet['A1'].value = df
>>> sheet['A1:C3'].options(pd.DataFrame).value
one two
0 1.1 2.2
1 3.3 NaN
# options: work for reading and writing
>>> sheet['A5'].options(index=False).value = df
>>> sheet['A9'].options(index=False, header=False).value = df
Pandas Series¶
>>> import pandas as pd
>>> import numpy as np
>>> sheet = xw.Book().sheets[0]
>>> s = pd.Series([1.1, 3.3, 5., np.nan, 6., 8.], name='myseries')
>>> s
0 1.1
1 3.3
2 5.0
3 NaN
4 6.0
5 8.0
Name: myseries, dtype: float64
>>> sheet['A1'].value = s
>>> sheet['A1:B7'].options(pd.Series).value
0 1.1
1 3.3
2 5.0
3 NaN
4 6.0
5 8.0
Name: myseries, dtype: float64
注意
在将列表、NumPy 数组或 Pandas DataFrame 写入 Excel 时,您只需指定左上角单元格即可,例如:sheet['A1'].value = np.eye(10)
分块:读取/写入大数据帧等¶
当你从大范围读取数据或写入数据时,你可能需要分块处理,否则会遇到超时或内存错误。理想的chunksize
将取决于你的系统和数组的大小,因此你需要尝试几种不同的分块大小以找到一个适合的:
import pandas as pd
import numpy as np
sheet = xw.Book().sheets[0]
data = np.arange(75_000 * 20).reshape(75_000, 20)
df = pd.DataFrame(data=data)
sheet['A1'].options(chunksize=10_000).value = df
并且读取也是一样的:
# As DataFrame
df = sheet['A1'].expand().options(pd.DataFrame, chunksize=10_000).value
# As list of list
df = sheet['A1'].expand().options(chunksize=10_000).value