Python学习系列之padas-DataFrame

1 引言

Python padas是常用的数据处理和分析模块,有特别的数据结构DataFrame。创建一个对象:

import pandas as pd
data=[[1,2,3],[4,5,6]]
index=['a','b']#行号
columns=['c','d','e']#列号
df=pd.DataFrame(data,index=index,columns=columns)#生成一个数据框

2 常遇到的错误

read_csv是常用的读取CSV格式的文件,其返回值就是DataFrame。新手很容易犯错认为DataFrame和array及list相同,可以用[][]来去行列中单个数据及切片数据:

比如:

ServiceLogs,98706832行x14列,8.77 GB,交易日志数据,每个交易会话可以有多条交易,A
ServiceCodes,286行×8列,20 KB,交易分类的字典表,B
df = pd.read_csv(path, header=None) # 不设置header=None,默认第一行为头,也就是列索引
print(df)

              0              1        2                     3  4
0   ServiceLogs  98706832行x14列  8.77 GB  交易日志数据,每个交易会话可以有多条交易  A
1  ServiceCodes        286行×8列    20 KB              交易分类的字典表  B

print(df[0][1])

ServiceCodes

 可以看到输出第一行,第二列竟然是第二行第一列。那是因为DataFrame的取值根本与array及list不同,但是如果习惯这样操作可以将DataFrame转为array。这样结果如大家所预料。

arr_df = np.array(df)
print(arr_df)
print(arr_df[0][1])

[['ServiceLogs' '98706832\xe8\xa1\x8cx14\xe5\x88\x97' '8.77 GB'
  '\xe4\xba\xa4\xe6\x98\x93\xe6\x97\xa5\xe5\xbf\x97\xe6\x95\xb0\xe6\x8d\xae\xef\xbc\x8c\xe6\xaf\x8f\xe4\xb8\xaa\xe4\xba\xa4\xe6\x98\x93\xe4\xbc\x9a\xe8\xaf\x9d\xe5\x8f\xaf\xe4\xbb\xa5\xe6\x9c\x89\xe5\xa4\x9a\xe6\x9d\xa1\xe4\xba\xa4\xe6\x98\x93'
  'A']
 ['ServiceCodes' '286\xe8\xa1\x8c\xc3\x978\xe5\x88\x97' '20 KB'
  '\xe4\xba\xa4\xe6\x98\x93\xe5\x88\x86\xe7\xb1\xbb\xe7\x9a\x84\xe5\xad\x97\xe5\x85\xb8\xe8\xa1\xa8'
  'B']]
98706832行x14列

 3 那原因是什么那?

原因主要是在DataFrame中直接用方括号取值是索引,也就是列索引,然后是行索引。比如:

df['a']#取a列
df[['a','b']]#取a、b列

而在未指定索引,比如指定names参数(列索引),index_col参数(行索引)及header=None。默认行列索引分别为0-(num-1),所以也就阴差阳错出现上述情况。下面我们可以测试当修改行列索引之后,是否可以继续按照错误方法调用?

df = pd.read_csv(path2, header=None, names=list('abcde'))
print(df)
print(df[0][1])

              a              b        c                     d  e
0   ServiceLogs  98706832行x14列  8.77 GB  交易日志数据,每个交易会话可以有多条交易  A
1  ServiceCodes        286行×8列    20 KB              交易分类的字典表  B

Traceback (most recent call last):
print(df[0][1])
...
KeyError: 0

也就是提示我们键(Key)错误,无0这个键,因为列索引,也就是键已经改成了a,b,c,d,e。对行也是如此。 

用索引则可以输出:

print(df["a"][1])
ServiceCodes

下面测试行索引:首先介绍参数 index_col,该参数是指定某一列为行索引,指定时可以使用标签索引或数字索引。

df = pd.read_csv(path2, header=None, names=list('abcde'), index_col=4)

df = pd.read_csv(path2, header=None, names=list('abcde'), index_col='e')
print(df)

              a              b        c                     d
e                                                            
A   ServiceLogs  98706832行x14列  8.77 GB  交易日志数据,每个交易会话可以有多条交易
B  ServiceCodes        286行×8列    20 KB              交易分类的字典表

 对于列来说不同点就是,可以使用即使指定了标签,也可以使用标签或者数字进行索引。

print(df["a"][1])
print(df["a"]["B"])

ServiceCodes
ServiceCodes

4 如何查找DataFrame的数据?

对于很多人来说先 “列”,后 “行”的索引方法,是不舒服的,但是实际上DataFrame内置有很多函数来查找取值。

at——通过行标签索引行数据(单个)
iat——通过行号索引行数据 (单个)

loc——通过行标签索引行数据 (切片)
iloc——通过行号索引行数据 (切片)
ix——通过行标签或者行号索引行数据(基于loc和iloc 的混合) (切片)
同理,索引列数据也是如此!

at:

print(df.at["A", "a"])

ServiceLogs

print(df.at["A", 1])

raise ValueError("At based indexing on an non-integer "
ValueError: At based indexing on an non-integer index can only have non-integer indexers

提醒我们at函数必须要标签索引,必需是非整型的参数。

iat:

print(df.iat[0, 1])

98706832行x14列

print(df.iat[0, "b"])

    raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers

提醒我们iat函数必须要行号索引,必需是整型的参数。

print(df.iat[0:1, 1])

    raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers

print(df.iat[0, 0:1])

    raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers

print(df.at["A", "a":"e"])

TypeError: unhashable type

print(df.at["A":"B", "a"])

TypeError: 'slice('A', 'B', None)' is an invalid key

不能使用切片代表。

iloc:

print(df.iloc[0, 1])

98706832行x14列

print(df.iloc[0, 1:2])

b    98706832行x14列
Name: A, dtype: object

 支持单个数值和切片,切片操作输出行列标签和类型。

print(df.iloc["A", "b"])

print(df.iloc["A":"B", "b"])

ValueError: Location based indexing can only have [integer, integer slice (START point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array] types

基于位置的索引只能是整数及整数切片, 前一个数值包括,后一个数值不包括。

loc:

print(df.loc["A", "b"])

98706832行x14列


print(df.loc["A":"B", "b"])

e
A    98706832行x14列
B          286行×8列
Name: b, dtype: object

print(df.loc["A", "b":"e"])

b           98706832行x14列
c                 8.77 GB
d    交易日志数据,每个交易会话可以有多条交易
Name: A, dtype: object


print(df.loc["A":"B", "b":"e"])

               b        c                     d
e                                              
A  98706832行x14列  8.77 GB  交易日志数据,每个交易会话可以有多条交易
B        286行×8列    20 KB              交易分类的字典表

注意:标签的索引是包括开头和结尾的标签。同样给出行列标签和类型。以切片方向为主。

但不能用行号索引:

print(df.loc[0, 1])

TypeError: cannot do label indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <type 'int'>

print(df.loc[0, 1:2])

TypeError: cannot do label indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <type 'int'>

ix:可以实现上述所有操作。

print(df.ix[0, 1])

98706832行x14列

print(df.ix[0, 0:2])

a      ServiceLogs
b    98706832行x14列
Name: A, dtype: object

print(df.ix["A", "b"])

98706832行x14列

print(df.ix["A":"B", "b"])

e
A    98706832行x14列
B          286行×8列
Name: b, dtype: object

at及iat必须要具体位置,不能输出一行或一列。其他操作可以直接输出一行或一列。方括号嵌套方括号是选值

df['a']#取a列
df[['a','b']]#取a、b列

#ix可以用数字索引,也可以用index和column索引
row0 = df.ix[0]#取第0行

row1 = df.ix[0:1]#取第0行
# print(row1)

a = df.ix['one':'two']#取one、two行
# print(a)

b = df.ix[0:2,0]#取第0、1行,第0列
# print(b)

c = df.ix[0:1,'a']#取第0行,a列
print(c)

d = df.ix[0:2,'a':'c']#取第0、1行,abc列
print(d)

c = df.ix['one':'two','a':'c']#取one、two行,abc列
# print(c)

d = df.ix[0:2,0:1]#取第0、1行,第0列
# print(d)

e = df.ix[0:2,0:2]#取第0、1行,第0、1列
# print(e)

#loc只能通过index和columns来取,不能用数字
f = df.loc['one','a']#one行,a列
print(f)

df.loc['one':'two','a']#one到two行,a列
df.loc['one':'two','a':'c']#one到two行,a到c列
df.loc['one':'two',['a','c']]#one到two行,ac列

#iloc只能用数字索引,不能用索引名
g = df.iloc[1:2]#前2行
print(g)

df.iloc[0]#第0行
df.iloc[0:2,0:2]#0、1行,0、1列
df.iloc[[0,2],[1,2,3]]#第0、2行,1、2、3列

#iat取某个单值,只能数字索引
df.iat[1,1]#第1行,1列
#at取某个单值,只能index和columns索引
df.at['one','a']#one行,a列
   c  d  e
a  1  2  3
b  4  5  6

print df.loc['a']
print df.ix['a']

c    1
d    2
e    3
Name: a, dtype: int64

print df.iloc[1]
print df.ix[1]

c    4
d    5
e    6
Name: b, dtype: int64

print df.at['a']
    return self.obj.get_value(*key, takeable=self._takeable)
TypeError: get_value() takes at least 3 arguments (3 given)

print df.iat[1]
   return self.obj.get_value(*key, takeable=self._takeable)
TypeError: get_value() takes at least 3 arguments (3 given)

其中取多列可以用print df.ix[:,0:2]。

<think>好的,我现在要解决用户的问题:“padas如何将第二列float转换为字符”。首先,我需要确认用户是否指的是“pandas”库,因为“padas”可能是拼写错误。根据用户之前的问题涉及pandas,所以应该确实是pandas的问题。 接下来,用户的问题是将DataFrame中的第二列从float类型转换为字符类型。我需要回忆pandas中数据类型转换的方法。通常,转换数据类型可以使用astype()方法,但用户需要的是转换为字符,也就是字符串类型。在pandas中,字符串类型对应的通常是object类型或者使用StringDtype(pandas 1.0以后引入的)。 用户提到的是第二列,所以需要确定如何定位到第二列。可以通过列名或者位置索引。如果使用位置索引,可以用iloc,比如df.iloc[:,1]。不过更常见的是通过列名,所以可能需要先确认列名是否存在或者是否有空格等问题。 然后,用户可能的场景是处理数据时,某些数值列需要转换为字符串,比如为了保留前导零或者特定格式。例如,将123.0转换为"123"或者"123.0"。这时候需要注意转换后的格式是否符合需求,是否需要去除小数点后的零。 此外,还需要考虑是否有缺失值。如果列中有NaN,转换为字符串时会变成'nan',这可能不是用户想要的,需要提醒用户注意处理缺失值的情况。 另外,可能用户的数据中第二列是float类型,但实际应该作为字符串处理,比如ID列,这时候需要确保转换后的正确性。例如,使用astype(str)可能会将123.45变成"123.45",但如果用户需要整数部分,可能需要先转换为整数再转字符串,或者使用格式化字符串。 还需要考虑性能问题,对于大型数据集,astype(str)和astype('string')可能有不同的表现,后者在pandas中是明确支持字符串的类型,可能会有更好的性能和内存使用。 可能用户之前尝试过某些方法但遇到了问题,比如转换后仍有小数部分,或者出现科学计数法,需要指导正确的转换方法以及格式化技巧。 最后,应该给出示例代码,说明如何正确转换,并提醒常见的注意事项,如列名引用、缺失值处理、格式调整等。同时,检查是否有拼写错误,比如pandas写成padas,可能在代码中也会出现类似错误,需要指出。</think>以下是使用Pandas将DataFrame第二列从float类型转换为字符串的三种常用方法: --- ### 方法1:基础类型转换 ```python df.iloc[:, 1] = df.iloc[:, 1].astype(str) # 按位置选择第二列 # 或 df['column_name'] = df['column_name'].astype(str) # 按列名选择 ``` ⚠️ **注意**:这会保留小数点(如123.0→"123.0") --- ### 方法2:格式化转换(推荐) ```python # 去除小数点后的0(123.0→"123") df['column_name'] = df['column_name'].apply(lambda x: f"{int(x)}" if x.is_integer() else str(x)) ``` --- ### 方法3:使用Pandas字符串类型 ```python df['column_name'] = df['column_name'].astype('string') # Pandas 1.0+版本支持 ``` ✅ **优势**: - 明确表示字符串类型 - 避免object类型的不确定性 - 更好的内存管理 --- ### 🚨 注意事项 1. **缺失值处理**: - NaN会转换为字符串"nan" - 建议先处理缺失值: ```python df['column_name'] = df['column_name'].fillna(-1).astype(str) ``` 2. **科学计数法问题**: ```python pd.set_option('display.float_format', '{:.0f}'.format) # 禁用科学计数法 ``` 3. **保留小数位数**: ```python df['column_name'] = df['column_name'].round(2).astype(str) # 保留两位小数 ``` --- ### 完整示例 ```python import pandas as pd import numpy as np # 示例数据 df = pd.DataFrame({ 'A': [1.0, 2.5, np.nan], 'B': [123456.0, 3.1415, 7.0], 'C': [10.0, 20.0, 30.0] }) # 转换第二列(B列) df['B'] = df['B'].apply(lambda x: f"{int(x)}" if not pd.isna(x) and x.is_integer() else str(x)) # 处理缺失值 df['B'] = df['B'].replace('nan', 'N/A') print(df) ``` 输出结果: ``` A B C 0 1.0 123 10.0 1 2.5 3.1415 20.0 2 NaN 7 30.0 ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值