pandas

一、删除相关

1.DataFrame.dropna()

DataFrame.dropna(self,axis=0,how=‘any’,thresh=None,subset=None,inplace=False):删除空值

axis{0或index,1或columns},默认0,删除包含缺失值的行或列。0或index:删除包含缺失值的行;1或columns:删除包含缺失值的列
how{any 或 all } ,默认为any。‘any’:如果存在任何nan值,则删除该行或列;‘all’:如果所有值均为nan,则删除该行或列
threshint,可选,需要许多非nan值
subset类数组,可选。要考虑的其他轴上的标签。例如,如果要删除行,这些标签将是要包括的列的列表。
inplacebool 默认为False.如果为True,则执行基地操作并返回None
返回删除了NA条目的DataFrame
补充:pd.NaT:缺失时间
import pandas as pd
import numpy as np

df = pd.DataFrame({
  "name":["Alfle","Bat","Cow"],
  "toy":[np.nan,"Batmobile","Bullwhip"],
  "born":[pd.NaT,pd.Timestamp("1940-04-25"),pd.NaT]
})
print("原始数据")
print(df)
print("-"*15)
print("删除至少缺少一个元素的行")
print(df.dropna())
print("-"*15)
print("删除至少缺少一个元素的列")
print(df.dropna(axis='columns'))
print("-"*15)
print("删除缺少所有元素的行")
print(df.dropna(how="all"))
print("-"*15)
print("只保留至少有两个非NA值的行")
print(df.dropna(thresh=2))
print("-"*15)
print("定义在哪些列中查找缺失值")
print(df.dropna(subset=['name','toy']))
print("-"*15)
print("将有有效条目的DataFrame保留在同一变量中")
df_two = df.dropna(inplace=True) #结果有点问题
print(df_two)
#结果:
原始数据
    name        toy       born
0  Alfle        NaN        NaT
1    Bat  Batmobile 1940-04-25
2    Cow   Bullwhip        NaT
---------------
删除至少缺少一个元素的行
  name        toy       born
1  Bat  Batmobile 1940-04-25
---------------
删除至少缺少一个元素的列
    name
0  Alfle
1    Bat
2    Cow
---------------
删除缺少所有元素的行
    name        toy       born
0  Alfle        NaN        NaT
1    Bat  Batmobile 1940-04-25
2    Cow   Bullwhip        NaT
---------------
只保留至少有两个非NA值的行
  name        toy       born
1  Bat  Batmobile 1940-04-25
2  Cow   Bullwhip        NaT
---------------
定义在哪些列中查找缺失值
  name        toy       born
1  Bat  Batmobile 1940-04-25
2  Cow   Bullwhip        NaT
---------------
将有有效条目的DataFrame保留在同一变量中
None

2.DataFrame.drop_duplicates()

drop_duplicates():返回删除了重复行的DataFrame,可选择仅考虑某些列。包括时间索引在内的索引将被忽略。

subset列标签或标签序列,可选。仅考虑用于签重复项的某列,默认情况下使用所有列
keep{‘first’,‘last’,False},-first:删除除第一次出现的重复项,-last:删除除最后一次出现的重复项。-False:删除所有重复项
inplacc布尔值,默认为False,是否删除重复项或返回副本
返回删除了重复行的DataFrame
import pandas as pd

test_dict = {
  "name":["Tom","Tom","Tom","Marry","John","John"],
  "fruit":["apple","apple","peach","peach","banana","banana"],
  "price":[3,3,5,6,7,8]
}
df = pd.DataFrame(test_dict)
print(df)
print("-"*15)
#默认情况下,它会根据所有列删除重复的行
new_df = df.drop_duplicates()
print(new_df)
print("-"*15)
#要删除特定列上的重复项,使用subset
df_subset = df.drop_duplicates(subset=["name"])
print(df_subset)
print("-"*15)
#要删除重复项并保留最后一次,使用keep
df_keep_two = df.drop_duplicates(subset=["name","fruit"],keep='last')
print(df_keep_two)
print("-"*15)
df_keep_three = df.drop_duplicates(subset=["name","fruit"],keep='first')
print(df_keep_three)
#结果:
    name   fruit  price
0    Tom   apple      3
1    Tom   apple      3
2    Tom   peach      5
3  Marry   peach      6
4   John  banana      7
5   John  banana      8
---------------
    name   fruit  price
0    Tom   apple      3
2    Tom   peach      5
3  Marry   peach      6
4   John  banana      7
5   John  banana      8
---------------
    name   fruit  price
0    Tom   apple      3
3  Marry   peach      6
4   John  banana      7
---------------
    name   fruit  price
1    Tom   apple      3
2    Tom   peach      5
3  Marry   peach      6
5   John  banana      8
---------------
    name   fruit  price
0    Tom   apple      3
2    Tom   peach      5
3  Marry   peach      6
4   John  banana      7

3.DataFrame.drop()

DataFrame.drop(labels=None,axis=0,index=None,columns=None,level=None,inplace=False,errors=‘raise’):从行或列中删除指定的标签。通过指定标签名和相应的轴,或直接指定索引或列名来删除行或列。使用索引时,可以通过指定级别来移除不同级别的标签

labels:单标签或者类似列表。要删除的索引或列标签。元组将用作单个标签,而不被视为类似列表
axis{0或‘index’,1或‘columns’} ,默认0。按照索引或列中删除标签
index单个索引或类似列表。替代指定轴(labels,axis=0 相当于index=labels)
columns单个索引或类似列表。替代指定轴(labels,axis=1,相当于columns=labels)
level整数或者层次名,可选。对于混合索引,是将要被移除的标签的层次
inplace布尔值,缺省为False。如果为False,返回一个副本,否则,就地执行操作并返回None
errors{‘ignore’,‘raise’} 默认‘raise’。如果‘ignore’,则抑制错误并且仅删除现有标签
返回值没有删除索引列或列标签的DataFrame或None if inplace=True
 df = pd.DataFrame(np.arange(12).reshape(3,4),columns=['A','B','C','D'])
 结果:
      A  B   C   D
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
  # 删除列
  df_one = df.drop(['B','C'],axis=1)
 结果:
    A   D
0  0   3
1  4   7
2  8  11
  df_two = df.drop(columns=['B','C'])
 结果:
    A   D
0  0   3
1  4   7
2  8  11
  # 按索引删除一行,左右都是闭区间
  df_three = df.drop([0,1])
结果:
   A  B   C   D
2  8  9  10  11
# 删除MultiIndex DataFrame的列/行
  midx = pd.MultiIndex(levels=[['sheep','cow','cat'],['speed','weight','length']],codes=[[0,0,0,1,1,1,2,2,2],[0,1,2,0,1,2,0,1,2]])
  df = pd.DataFrame(index=midx,columns=['big','small'],data=[[45,30],[200,100],[1.5,1],[30,20],[250,150],[1.5,0.8],[320,250],[1,0.8],[0.3,0.2]])
原始dataframe:
                big  small
sheep speed    45.0   30.0
      weight  200.0  100.0
      length    1.5    1.0
cow   speed    30.0   20.0
      weight  250.0  150.0
      length    1.5    0.8
cat   speed   320.0  250.0
      weight    1.0    0.8
      length    0.3    0.2
  # 从 MultiIndex DataFrame中删除特定的索引组合,即删除'cat'和'weight',它只删除对应的行
df.drop(index=('cat','weight')):
                big  small
sheep speed    45.0   30.0
      weight  200.0  100.0
      length    1.5    1.0
cow   speed    30.0   20.0
      weight  250.0  150.0
      length    1.5    0.8
cat   speed   320.0  250.0
      length    0.3    0.2
      
df.drop(index='cow',columns='small'):

                big
sheep speed    45.0
      weight  200.0
      length    1.5
cat   speed   320.0
      weight    1.0
      length    0.3

df.drop(index='length',level=1) # level说明 length是哪一层索引
  结果:

                big  small
sheep speed    45.0   30.0
      weight  200.0  100.0
cow   speed    30.0   20.0
      weight  250.0  150.0
cat   speed   320.0  250.0
      weight    1.0    0.8

二、索引相关

1.DataFrame.sort_index()

DataFrame.sort_index(axis=0,level=None,ascending=True,inplace=False,kind=‘quicksort’,na_position=‘last’,sort_remaining=True,ignore_index=False,key=None)
按标签(沿轴)对对象排序
如果inplace参数为False,返回按标签排序的新DataFrame,否则更新原始DataFrame并返回None

axis{0 或‘index’,1或‘columns’},默认为0,0表示行,1表示列
levelint 或level name 或 ints的list 或level names的list,如果不为None,则按指定索引级别的值排序
ascendingbool 或bools的list ,默认为True。升序和降序排序。当索引是多索引时,排序方向可以为每个级别单独控制
inplacebool,默认为False。如果为True,就地执行操作
kind{‘quicksort’,‘mergesort’,‘heapsort’}默认为’quicksort’。mergesort是唯一稳定的算法,对于DataFrame,仅在对单个列或标签进行排序时才应用此选项
na_position{‘first’,‘last’ } 默认为‘last’,如果首先将NaN放在开头;最后将NaN放在最后。未针对MultiIndex实施。
sort_remainingbool,默认为True.如果为True且按级别和索引排序是多层的,则在按指定级别排序后也按其他级别(按顺序)排序
ignore_indexbool,默认为False。如果为True,则结果轴将标记为0,1,…,n-1
keycallable,可选的。如果不是None,则在排序之前将函数应用于索引值。这类似于内建函数中的key参数sorted(),但值得注意的区别是此key函数应被向量化。它应期望index并返回具有相同形状的index。对于MultiIndex输入,将按级别应用key
返回原始DataFrame按标签排序
import pandas as pd
#默认情况下,它以升序排序,要想降序排序,使用ascending=False
test_dict = {
  "A": [1,2,3,4,5]
}
df = pd.DataFrame(test_dict,index=[100,29,234,1,150])
print(df)
new_df = df.sort_index()
print(new_df)
new_descent_df = df.sort_index(ascending=False)
print(new_descent_df)
#结果:
    A
100  1
29   2
234  3
1    4
150  5

     A
1    4
29   2
100  1
150  5
234  3

     A
234  3
150  5
100  1
29   2
1    4

# 可以指定在排序之前对索引的键进行处理
test_dict_two = {
  "a":[1,2,3,4]
}
df_two = pd.DataFrame(test_dict_two,index=["A","b","C","d"])
print(df_two)
new_df_two = df_two.sort_index()
print(new_df_two)
new_key_df = df_two.sort_index(key=lambda x:x.str.lower())
print(new_key_df)
#结果:
   a
A  1
b  2
C  3
d  4

   a
A  1
C  3
b  2
d  4

   a
A  1
b  2
C  3
d  4

2.DataFrame.reset_index()

3.DataFrame.isna()

检测缺失值。返回一个布尔值相同大小的对象,指示值是否为NA。例如None或numpy.NAN,被映射到True值。其他所有内容都被映射到False值。如空字符串‘’或numpy.inf不被视为NA值的字符(除非设置)

返回DataFrame,DataFrame中每个元素的布尔值掩码,指示每个元素是否为NA值

4.DataFrame.groupby()

groupby(by=None,axis =0,level=None,as_index=True,sort=True,group_keys=True,observed = False,dropna = True):使用映射器或一系列列对DataFrame进行分组

by:映射、函数、标签或标签列表,用于确定groupby的组。如果by是一个函数,它会在对象索引的每个值上调用。如果传递了dict或Series,则Series或dict 的值将用于确定组。如果传递长度等于所选轴的列表qu或ndarray,则按原样使用这些值来确定组。标签或标签列可以按self.请注意,元组被解释为(单个)键
axis{0 或‘index’,1 或‘columns’},默认为0,沿行(0)或列(1) 拆分
levelint,level name ,or sequence of such,default None,如果轴是MultiIndex(分层),则按特定级别或多个级别分组
as_index布尔值,默认为True,对于聚合输出,返回以组标签为索引的对象。仅与DataFrame输入相关。as_index=False 实际上是“SQL风格”的分组输出
sort布尔值,默认为True,对组键进行排序。关闭此功能会获得更好的性能。注意,这不会影响每组内的观察顺序。Groupby保留每个组内的行顺序
group_keys布尔值,默认为True,调用apply时,将组键添加到索引以识别片段
observed布尔值,默认为False,这仅适用于任何groupers是分类的。如果为真:仅显示分类分组的观察值。如果为False,显示分类分组的所有值
dropna布尔值,默认为True。如果为True,并且组键包含NA值,则NA值连同行/列都被删除。如果为False,NA值也将被视为组中的键
import pandas as pd

df = pd.DataFrame({
  "animal":["falcon","falcon","parrot","parrot"],
  "max speed":[380,370,24,26]
})
print(df)
print(df.groupby(['animal']).mean())
print("-"*15)
print("层次索引:可以使用level参数对分层索引的不同级别进行分组")
# 层次索引:可以使用level参数对分层索引的不同级别进行分组
arrays = [
  ['Falcon', 'Falcon', 'Parrot', 'Parrot'],  # falcon:猎鹰
  ['Captive', 'Wild', 'Captive', 'Wild']  # 俘虏,囚徒,战俘
]
index = pd.MultiIndex.from_arrays(arrays,names=('animal','type'))
df_two = pd.DataFrame({'max speed':[390,350,30,20]},index=index)
print(df_two)
print(df_two.groupby(level=0).mean())
print(df_two.groupby(level='type').mean())
print("-"*15)
print("可以通过设置dropna参数来选择是否在主键中包含NA,默认设置为True")
# 可以通过设置dropna参数来选择是否在主键中包含NA,默认设置为True
l = [[1,2,3],[1,None,4],[2,1,3],[1,2,2]]
df_three = pd.DataFrame(l,columns=["a","b","c"])
print(df_three)
print("~"*10)
print(df_three.groupby(by=["b"]).sum())
print("~"*10)
print(df_three.groupby(by=["b"],dropna=False).sum())
print("~"*10)
print("-"*15)
#结果:
   animal  max speed
0  falcon        380
1  falcon        370
2  parrot         24
3  parrot         26
        max speed
animal           
falcon        375
parrot         25
---------------
层次索引:可以使用level参数对分层索引的不同级别进行分组
                max speed
animal type              
Falcon Captive        390
       Wild           350
Parrot Captive         30
       Wild            20
        max speed
animal           
Falcon        370
Parrot         25
         max speed
type              
Captive        210
Wild           185
---------------
可以通过设置dropna参数来选择是否在主键中包含NA,默认设置为True
   a    b  c
0  1  2.0  3
1  1  NaN  4
2  2  1.0  3
3  1  2.0  2
~~~~~~~~~~
     a  c
b        
1.0  2  3
2.0  2  5
~~~~~~~~~~
     a  c
b        
1.0  2  3
2.0  2  5
NaN  1  4

5.DataFrame.nunique()获得行或者列重复的个数

nunique(axis=0,dropna = True):计算指定轴中不同元素的数量。返回具有不同元素数量的序列。可以忽略NAN值。

axis{0 或‘index’,1 或’columns‘},默认0,要使用的轴。0 或’index’表示行,1或’columns’表示列
dropna布尔值,默认为True。不要在计数中包含NAN
返回值Series
df = pd.DataFrame({'A': [4, 5, 6], 'B': [4, 1, 1]})
print("df\n",df)
print("df.nunique\n",df.nunique())
print("df.nuique(axis=1)\n",df.nunique(axis=1))
结果:
df:
   A  B
0  4  4
1  5  1
2  6  1


df.nunique:
A    3
B    2
dtype: int64


df.nuique(axis=1)0    1
1    2
2    2
dtype: int64

三、时间相关

pandas中有4个和时间相关的一般概念

  1. 日期时间:具有时区支持的特定日期和时间。类似于datetime.datetime标准库
  2. 时间增量:绝对持续时间。类似于datetime.timedelta标准库
  3. 时间跨度:由时间点及其相关频率定义的时间跨度
  4. 日期偏移量:来自dateutil包的dateutil.relativedelta.relativedelta相似
日期时间to_datetime 或者date_range
时间增量to_timedelta或者timedelta_range
时间跨度Period 或者period_range
日期偏移DateOffset

3. DataFrame.tz_convert()

4. DataFrame.tz_localize()

四、查询相关

1.DataFrame.query()

2.DataFrame.where()

3.DataFrame.at()

4.DataFrame.loc()

5.DataFrame.iloc()

五、数据格式转换

1.dataframe.to_dict()

2.DataFrame.to_sql()

3.DataFrame.read_sql()

六、连表查询相关

1. DataFrame.merge()

dataframe.merge(right,how=‘inner’,on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False,suffixes=(‘_x’,‘_y’),copy=True,indicator=False,validate=None):将DataFrame或命名的Series对象与数据库样式的连接合并。命名的Series对象被视为具有单个命名列的DataFrame。连接是在列或索引上完成的。如果在列上连接列,DataFrame索引将被忽略。否则,如果加入索引上的索引或列上的索引,则索引将被传递。执行交叉合并时,不允许合并列规范。
注意:
如果两个键列都包含键为空值的行,则这些行将相互匹配。这与通常的SQL连接行行为不同,并可能导致意外结果。

rightDataFrame或命名的Series,即要合并的对象
how{‘left’,‘right’,‘outer’,‘inner’,‘cross’},默认‘inner’,要执行的合并类型。left:仅使用来自左边frame的键,并保留键的顺序;right:仅使用来自右边frame的键,并保留键的顺序;outer:使用两个frame的并集,按字典顺序对键进行排序;inner:使用两个frame的交集,保留左键的顺序;cross:使用两个frame创建笛卡尔积,保留左键的顺序
on标签或列表。要加入的列或索引级别名称。这些必须在两个dataframe中都可以找到。如果on是None并且不合并索引,则默认为两个dataframe中列的交集
left_on标签或列表或类似数组,要在左侧DataFrame中加入的列或索引级别名称。也可以是左侧DataFrame长度的数组或数组列表。这些数组被视为列
right_on标签或列表或类似数组,要在右侧DataFrame中加入的列或索引级别名称。也可以是右侧DataFrame长度的数组或数组列表。这些数组被视为列。
left_index布尔值,默认为False。使用左侧dataframe中的索引作为连接键。如果是MultiIndex,则另一dataframe中的键数(索引或列数)必须与级别数匹配
right_index布尔值,默认为False。使用右侧dataframe中的索引作为连接键
sort布尔值,默认为False,在结果dataframe中按字典顺序对连接键进行排序。如果为False,则连接键的顺序取决于连接类型(how关键字)
suffixes
copy布尔值,默认为True。如果为False,请尽可能避免复制
indicator
validatestr,可选。如果指定,则检查合并是否属于指定类型。“one_to_one"或"1:1”:检查合并键在左右数据集中是否唯一;“one_to_many"或"1:m”:检查合并键在左侧数据集中是否唯一;“many_to_one"或"m:1”:检查合并建在右边的数据集中是否唯一
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo'],
                    'value': [1, 2, 3, 5]})
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo'],
                    'value': [5, 6, 7, 8]})
print("df1\n",df1)
print("df2\n",df2)
# 在 lkey 和 rkey 列上合并df1 和 df2。值列附加了默认后缀 _x 和 _y。
df3 = pd.merge(df1,df2,left_on='lkey',right_on='rkey')
print("df3\n",df3)
# 合并DataFrames df1 和 df2,并在任何重叠列上附加指定的左右后缀。
df4 = pd.merge(df1,df2,left_on='lkey',right_on='rkey',suffixes=('_left','_right'))
print("df4\n",df4)
# 合并DataFrames df1 和 df2,但如果 DataFrames 有任何重叠列,则会引发异常。
# df4 = pd.merge(df1, df2, left_on='lkey', right_on='rkey', suffixes=(False,False))
test1 = pd.DataFrame({'a': ['foo', 'bar'], 'b': [1, 2]})
test2 = pd.DataFrame({'a': ['foo', 'baz'], 'c': [3, 4]})
print("test1\n",test1)
print("test2\n",test2)
test3=pd.merge(test1,test2,on='a',how='inner')
print("test3\n",test3)
test4 = pd.merge(test1,test2,on='a',how='left')
print("test4\n",test4)
# 笛卡尔积
data1 = pd.DataFrame({'left': ['foo', 'bar']})
data2 = pd.DataFrame({'right': [7, 8]})
print("data1\n",data1)
print("data2\n",data2)
data3 = pd.merge(data1,data2,how="cross")
print("data3\n",data3)
结果:
df1
   lkey  value
0  foo      1
1  bar      2
2  baz      3
3  foo      5
df2
   rkey  value
0  foo      5
1  bar      6
2  baz      7
3  foo      8
df3
   lkey  value_x rkey  value_y
0  foo        1  foo        5
1  foo        1  foo        8
2  foo        5  foo        5
3  foo        5  foo        8
4  bar        2  bar        6
5  baz        3  baz        7
df4
   lkey  value_left rkey  value_right
0  foo           1  foo            5
1  foo           1  foo            8
2  foo           5  foo            5
3  foo           5  foo            8
4  bar           2  bar            6
5  baz           3  baz            7
test1
      a  b
0  foo  1
1  bar  2
test2
      a  c
0  foo  3
1  baz  4
test3
      a  b  c
0  foo  1  3
test4
      a  b    c
0  foo  1  3.0
1  bar  2  NaN
data1
   left
0  foo
1  bar
data2
    right
0      7
1      8
data3
   left  right
0  foo      7
1  foo      8
2  bar      7
3  bar      8

2.DataFrame.join()

dataframe.join(other,on=None,how=‘left’,lsuffix=‘’,rsuffix=‘’,sort=False):
在索引或键列上将列与其他dataframe连接。通过传递一个列表,一次有效的按索引连接多个dataframe对象。

other:DataFrame、Series或DataFrame列表。索引应该类似于这一列中的一列。如果传递了Series,则必须设置其name属性,并将其用作生成的DataFrame中的列名
on:字符串、字符串列表或类似数组的情况,可选字段。调用者中的列或
how:{‘left’,‘right’,‘outer’,‘inner’},默认‘left’。表示如何处理这两个对象的操作。left:使用调用框架的索引(或指定的列);right:使用other的索引;outer:将调用框架的索引(如果指定了on,则为列)与其他索引形成联合,并对其进行排序。按字典顺序;inner:形成调用框架的索引(或指定了on的列)与其他索引的交集,保留调用的索引的顺序;cross:从两个帧创建笛卡尔积,保留左键的顺序。
lsuffix:从左框架的重叠列中使用的后缀
rsuffix:从右框架的重叠列中使用的后缀
sort:布尔值,默认为False。通过连接键按字典顺序对结果DataFrame进行排序。如果为False,则连接键的顺序取决于连接类型(how 关键字)
返回值包含来自调用者和其他列的DataFrame

3. DataFrame.concat()

七、处理每个元素相关

1.DataFrame.apply()

2.DataFrame.applymap()

八、具体应用场景相关

1. dataframe中按照某一列的值将其他列合并

方法一:

data = {
    "uuid":[1,2,3,2,1],
    "fruit":["apple","peach","pear","watermelon","banana"]
  }
  df = pd.DataFrame(data)
  print(df)
  uuid_list = []
  for index,row in df.iterrows():
    in_dict = {}
    if row['uuid'] not in uuid_list:
      uuid_list.append(row['uuid'])
  test = [{x:list()} for x in uuid_list]
  print(test)
  for index, row in df.iterrows():
    key = row['uuid']
    for each in test:
      for k,v in each.items():
        if k == key:
          each[k].append(row['fruit'])
  print(test)
  #结果:
  df:
     uuid       fruit
0     1       apple
1     2       peach
2     3        pear
3     2  watermelon
4     1      banana
test:
[{1: []}, {2: []}, {3: []}]
test:
[{1: ['apple', 'banana']}, {2: ['peach', 'watermelon']}, {3: ['pear']}]

方法二:

 import pandas as pd
  import numpy as np

  # 读入数据
  test_df = {
    "姓名": ["张三","张三","张三","李四","李四","李四","王五","王五","赵六","赵六"],
    "爱好": ["旅游","画画","游泳","跳舞","打羽毛球","唱歌","打羽毛球","唱歌","旅游","唱歌"],
    "性别": ["男","男","男","女","女","女","男","男","女","女"]
  }
  df = pd.DataFrame(test_df)
  print("df:")
  print(df)
  # 定义拼接函数,并对字段进行去重
  def concat_func(x):
    return pd.Series({
      '爱好': x['爱好'].unique(),
      '性别': x['性别'].unique()
    })
  # 分组聚合+拼接
  result = df.groupby(df['姓名']).apply(concat_func).reset_index()
  # 结果展示
  print("result:")
  print(result)
  #结果:
  df:
   姓名    爱好 性别
0  张三    旅游  男
1  张三    画画  男
2  张三    游泳  男
3  李四    跳舞  女
4  李四  打羽毛球  女
5  李四    唱歌  女
6  王五  打羽毛球  男
7  王五    唱歌  男
8  赵六    旅游  女
9  赵六    唱歌  女
result:
   姓名              爱好   性别
0  张三    [旅游, 画画, 游泳]  []
1  李四  [跳舞, 打羽毛球, 唱歌]  []
2  王五      [打羽毛球, 唱歌]  []
3  赵六        [旅游, 唱歌]  []

2.dataframe中一列数据为list时分成多列或多行

参考:方法来源于该博客

from copy import deepcopy


def split_col(data, column):
    """拆分成列

    :param data: 原始数据
    :param column: 拆分的列名
    :type data: pandas.core.frame.DataFrame
    :type column: str
    """
    data = deepcopy(data)
    max_len = max(list(map(len, data[column].values)))  # 最大长度
    new_col = data[column].apply(lambda x: x + [None]*(max_len - len(x)))  # 补空值,None可换成np.nan
    new_col = np.array(new_col.tolist()).T  # 转置
    for i, j in enumerate(new_col):
        data[column + str(i)] = j
    return data


def split_cols(data, columns):
  """批量拆分成列并且不要原始列
  :param data: 原始数据
  :param columns: 拆分的列名
  :type data: pandas.core.frame.DataFrame
  :type columns: list
  """
  for c in columns:
    new_col = data.pop(c)
    max_len = max(list(map(len, new_col.values)))  # 最大长度
    new_col = new_col.apply(lambda x: x + [None] * (max_len - len(x)))  # 补空值,None可换成np.nan
    new_col = np.array(new_col.tolist()).T  # 转置
    for i, j in enumerate(new_col):
      data[c + str(i)] = j
  return data

def split_row(data, column):
  """拆分成行

  :param data: 原始数据
  :param column: 拆分的列名
  :type data: pandas.core.frame.DataFrame
  :type column: str
  """
  row_len = list(map(len, data[column].values))
  rows = []
  for i in data.columns:
    if i == column:
      row = np.concatenate(data[i].values)
    else:
      row = np.repeat(data[i].values, row_len)
    rows.append(row)
  return pd.DataFrame(np.dstack(tuple(rows))[0], columns=data.columns)
if __name__=="__main__":
	data ={
	'name':['小明','小红'],
	'hobby':[["running","swimming"],["sking","joging","drawing"]],
	"pet":[["dog","cat"],["rabbit","monkey","tiger"]]
	}
	df = pd.DataFrame(data)
	df_col = split_cols(df,["hobby","pet"])
	df_row = split_row(df,column="hobby")
结果:
df:
  name                     hobby                      pet
0   小明       [running, swimming]               [dog, cat]
1   小红  [sking, joging, drawing]  [rabbit, monkey, tiger]


df_col:
  name   hobby0    hobby1   hobby2    pet0    pet1   pet2
0   小明  running  swimming     None     dog     cat   None
1   小红    sking    joging  drawing  rabbit  monkey  tiger


df_row:
  name     hobby                      pet
0   小明   running               [dog, cat]
1   小明  swimming               [dog, cat]
2   小红     sking  [rabbit, monkey, tiger]
3   小红    joging  [rabbit, monkey, tiger]
4   小红   drawing  [rabbit, monkey, tiger]

3.dataframe中将两列数据相减,得到第三列数据

def x(a, b):
  d1 = datetime.datetime.strptime(str(a), '%Y-%m-%d %H:%M:%S')
  d2 = datetime.datetime.strptime(str(b), '%Y-%m-%d %H:%M:%S')
  delta = d1 - d2
  # 相减得到秒数,转化为小时,并四舍五入保留两位小数round(x,2)
  return round((delta.total_seconds() / 3600),2)


test_dict={
    "a":["2021-12-21 10:00:00","2022-04-07 12:00:00"],
    "c":["2021-12-21 11:30:00","2022-04-07 13:00:00"]
  }
  df = pd.DataFrame(test_dict)
  print(df)
  df['c-a'] = df.apply(lambda f: x(f['c'], f['a']), axis=1)
  print(df)
结果:
                     a                    c
0  2021-12-21 10:00:00  2021-12-21 11:30:00
1  2022-04-07 12:00:00  2022-04-07 13:00:00
                     a                    c  c-a
0  2021-12-21 10:00:00  2021-12-21 11:30:00  1.5
1  2022-04-07 12:00:00  2022-04-07 13:00:00  1.0

4.用dataframe.filter()过滤掉多余的数据列,减少数据量

dataframe.filter(items=None,like=None,regex=None,axis=None):根据指定的索引标签过滤dataframe的行或列

itemslist保留项目中的轴标签
likestr保留“like in label”的标签
regexstr正则表达式,保留re.search(regex,label)轴的标签
axis{0或index,1 或 columns}默认为None
test_data = {
"name": ["小蓝", "小红", "小绿"],
"hobby": ["swim", "run", "jog"],
"age": [10, 6, 7]
}
df = pd.DataFrame(test_data,index=['one','two','three'])
结果:

df=
      name hobby  age
one     小蓝  swim   10
two     小红   run    6
three   小绿   jog    7

df.filter(items=['name', 'age'])=
      name  age
one     小蓝   10
two     小红    6
three   小绿    7

df.filter(regex='y$', axis=1)=
      hobby
one    swim
two     run
three   jog

df.filter(like='e',axis=0)
      name hobby  age
one     小蓝  swim   10
three   小绿   jog    7

5.dataframe修改index,columns名的方法

一般常用的两个方法:

  1. 使用DataFrame.index=[newName],DataFrame.columns=[newNew]
  2. 使用DataFrame.rename()方法
    DataFrame.rename(mapper=None,index=None,columns=None,axis=None,copy=True,inplace=False,level=None)
mapper、index、columns可以任选其一使用,可以是将index和columns结合使用,index 和column直接传入mapper或者字典的形式
axis{0 或index,1 或columns},默认为index
copyboolean,默认为True,是否复制基础数据
inplaceboolean,默认为False,是否返回新的dataframe,如果为True,忽略复制值
test_data = {
    "name": ["小红", "小蓝", "小紫", "小粉"],
    "age": [5, 6, 7, 9],
    "hobby": ["swimming", "running", "joging","playing the piano"]
  }
df = pd.DataFrame(test_data)
print("orign df:\n",df)
   name  age              hobby
0   小红    5           swimming
1   小蓝    6            running
2   小紫    7             joging
3   小粉    9  playing the piano


df.index = ["one", "two", "three","four"]
print("df:\n",df)
df:
       name  age              hobby
one     小红    5           swimming
two     小蓝    6            running
three   小紫    7             joging
four    小粉    9  playing the piano


# 使用map方法进行映射
df.index = df.index.map(str.upper)
print("df:\n",df)
df:
       name  age              hobby
ONE     小红    5           swimming
TWO     小蓝    6            running
THREE   小紫    7             joging
FOUR    小粉    9  playing the piano


# 使用rename,可以分别为index 和 column 来指定值
df1 = df.rename(index=str.lower,columns=str.upper) # 这种方法是产生一个新dataframe
print("df1:\n", df1)
df1:
       NAME  AGE              HOBBY
one     小红    5           swimming
two     小蓝    6            running
three   小紫    7             joging
four    小粉    9  playing the piano


# rename 还可以传入字典
df2 = df1.rename(index={'two':2},columns={'NAME':'姓名'})
print("df2:\n", df2)
df2:

        姓名  AGE              HOBBY
one    小红    5           swimming
2      小蓝    6            running
three  小紫    7             joging
four   小粉    9  playing the piano


# rename 使用自定义的map 函数
def test_map(x):
  return "zh"+x
print(df1.index.map(test_map))
Index(['zhone', 'zhtwo', 'zhthree', 'zhfour'], dtype='object')
print("df1:\n",df1.rename(index=test_map))
df1:
         NAME  AGE              HOBBY
zhone     小红    5           swimming
zhtwo     小蓝    6            running
zhthree   小紫    7             joging
zhfour    小粉    9  playing the piano

6.dataframe中按照某一列进行排序

  1. dataframe.sort_values(by, axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’, ignore_index=False, key=None):按任一轴上的值排序
bystr 或 列表,要排序的名称或名称列表。如果轴为 0 或“索引”,则by可能包含索引级别和/或列标签。如果轴为 1 或“列”,则by可能包含列级别和/或索引标签
axis{0 或 ‘index’,1 或 ‘columns’},默认 0。要排序的轴
ascendingbool 或 bool 列表,默认 True
升序与降序排序。指定多个排序顺序的列表。如果这是一个布尔列表,则必须匹配 by 的长度。
kind{‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’},默认 ‘quicksort’。排序算法的选择。合并排序和稳定是唯一稳定的算法。对于 DataFrame,此选项仅在对单个列或标签进行排序时应用
na_position{‘first’,‘last’},默认’last’。如果first ,则将 NaNs 放在开头;最后将 NaN 放在最后。
ignore_index布尔值,默认为 False。如果为 True,则生成的轴将标记为 0、1、…、n - 1。
key可调用,可选在排序之前将键函数应用于值。这类似于内置函数中的keysorted()参数,显着的区别是这个key函数应该是矢量化的。它应该期望 a Series并返回一个与输入具有相同形状的系列。它将独立应用于by中的每一列
data={
  "name": ["小红", "小蓝", "小粉"],
  "score": [64, 26, 77]
}
df = pd.DataFrame(data)
print(df)
df.sort_values(by="score", ascending=False, inplace=True)
print(df)
结果:
df:
  name  score
0   小红     64
1   小蓝     26
2   小粉     77

after_sort_df:
  name  score
2   小粉     77
0   小红     64
1   小蓝     26
df = pd.DataFrame({
  "time": ['0hr', '128hr', '72hr', '48hr', '96hr'],
  "value": [10, 20, 30, 40, 50]
})
print(df)
    time  value
0    0hr     10
1  128hr     20
2   72hr     30
3   48hr     40
4   96hr     50


df.sort_values(
  by="time",
  key=lambda x: np.argsort(index_natsorted(df["time"]))
)
print(df)


    time  value
0    0hr     10
3   48hr     40
2   72hr     30
4   96hr     50
1  128hr     20
  1. dataframe.rank(axis=0, method=‘average’, numeric_only=NoDefault.no_default, na_option=‘keep’, ascending=True, pct=False):沿轴计算数值数据等级s(1 到 n)。默认情况下,为相等的值分配一个排名,该排名是这些值排名的平均值。
axis{0 或 ‘index’,1 或 ‘columns’},默认 0
直接排名的索引
method方法{‘average’, ‘min’, ‘max’, ‘first’, ‘dense’},默认 ‘average’
如何对具有相同值(即平局)的记录组进行排名:average:组的平均排名;min:组中的最低排名;max:组中的最高排名;first:按照它们在数组中出现的顺序分配的rank;dense:像’min’,但组间排名总是增加1。
na_option{‘keep’,‘top’,‘bottom’},默认’keep’。如何对NaN 值进行排名:keep:将 NaN等级分配给 NaN 值;top:为 NaN 值分配最低等级;botom:将最高等级分配给 NaN 值
numeric_only布尔值,可选。对于 DataFrame 对象,如果设置为 True,则仅对数字列进行排名。
ascending升序布尔值,默认 True。元素是否应按升序排列。
pct布尔值,默认为 False。是否以百分位形式显示返回的排名。
返回值:与调用者相同的类型,返回具有数据等级s 作为值的 Series 或 DataFrame。
 x = {"name": ["张三", "李四", "王五", "赵六"],
       "scores": [60, 40, 50, 40]}
df = pd.DataFrame(x)
print(df)
df["排名"] = df["sales"].rank(method="dense", ascending=False)
结果:
orgin_df:
  name  scores
0   张三      60
1   李四      40
2   王五      50
3   赵六      40

rank_df:
  name  scores   排名
0   张三      60  1.0
1   李四      40  3.0
2   王五      50  2.0
3   赵六      40  3.0

7. 行列转置

方法一:

df = pd.DataFrame({"姓名":["张三","张三","张三","李四","李四","李四","王五","王五","王五"],"科目":["数学","语文","英语","数学","语文","英语","数学","语文","英语"],"成绩":[90,89,79,91,92,97,90,89,87]})
print("df")
print(df)
df1 = df.set_index(['姓名','科目'])['成绩']
print("df1")
print(df1)
df2 = df1.unstack().fillna(0)
print("df2")
print(df2)
df3 = df2.rename_axis(columns=None)
print("df3")
print(df3)
df4 = df3.reset_index()
print("df4")
print(df4)


结果:
df
   姓名  科目  成绩
0  张三  数学  90
1  张三  语文  89
2  张三  英语  79
3  李四  数学  91
4  李四  语文  92
5  李四  英语  97
6  王五  数学  90
7  王五  语文  89
8  王五  英语  87
df1
姓名  科目
张三  数学    90
    语文    89
    英语    79
李四  数学    91
    语文    92
    英语    97
王五  数学    90
    语文    89
    英语    87
Name: 成绩, dtype: int64
df2
科目  数学  英语  语文
姓名            
张三  90  79  89
李四  91  97  92
王五  90  87  89
df3
    数学  英语  语文
姓名            
张三  90  79  89
李四  91  97  92
王五  90  87  89
df4
   姓名  数学  英语  语文
0  张三  90  79  89
1  李四  91  97  92
2  王五  90  87  89

  • pd.set_index()
    (1) 将一列作为索引
    (2)设置复合索引
    (3)设置复合索引源码
  • pd.unstack()
  • pd.fillna()
  • pd.rename_axis()
  • pd.reset_index()
  • pd.pivot()

方法二:

df = pd.DataFrame({"姓名":["张三","张三","张三","李四","李四","李四","王五","王五","王五"],"科目":["数学","语文","英语","数学","语文","英语","数学","语文","英语"],"成绩":[90,89,79,91,92,97,90,89,87]})
df6 = pd.pivot(df,index='姓名',columns='科目',values='成绩').rename_axis(columns=None).reset_index().fillna(0)
print("df6")
print(df6)
结果:
df6
   姓名  数学  英语  语文
0  张三  90  79  89
1  李四  91  97  92
2  王五  90  87  89

8.分组并得到每组的值

 df = pd.DataFrame({"动物":["dog","rabbit","cat","dog"],"食物":["apple","carrot","fish","meat"]})
    final =[]
    for table,item in df.groupby('动物'):
        print(table)
        temp={}
        temp[table]=[]
        for index,row in item.iterrows():
            temp[table].append(row['食物'])
        final.append(temp)
    print(final)

结果:
cat
dog
rabbit
[{'cat': ['fish']}, {'dog': ['apple', 'meat']}, {'rabbit': ['carrot']}]

9. pd.to_dict()

10. pd.to_numeric()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值