2.pandas入門介紹

来源:https://www.cnblogs.com/bonheur/archive/2020/03/07/12431805.html
-Advertisement-
Play Games

前面知道NumPy是 Python 語言的一個擴展程式庫,支持大量的維度數組與矩陣運算,也針對數組運算提供大量的數學函數庫。numpy是基於c語言開發,所以這使得numpy的運行速度很快,高效率運行就是numpy的一大優勢。但numpy的特長並不是在於數據處理,而是在於能非常方便地實現科學計算,所以 ...


前面知道NumPy是 Python 語言的一個擴展程式庫,支持大量的維度數組與矩陣運算,也針對數組運算提供大量的數學函數庫。numpy是基於c語言開發,所以這使得numpy的運行速度很快,高效率運行就是numpy的一大優勢。但numpy的特長並不是在於數據處理,而是在於能非常方便地實現科學計算,所以對數據進行處理時用的numpy情況並不是很多,因為需要處理的數據一般都是帶有列標簽和index索引的,而numpy並不支持這些,這時就需要pandas了,Pandas的主要工作就是做數據分析,pandas繼承了numpy  我們要使用的是pandas而不是numpy。Pandas是基於Numpy構建的庫,在數據處理方面可以把它理解為numpy加強版 。

數據分析中:樣本是(行)  特征是(列)。

pandas的優缺點。優點:pandas相比於Excel,matlab,tableau等更加的靈活,處理大數據的問題上更加有優勢,讀取excel文件的時候,pandas更加快,處理速度快。缺點:操控方面相對比較僵硬,pandas當中的函數要清晰使用,statsmodels統計庫(bug百出,官網提供的文檔大部分不友好),scipy高數(stats,使用方法太繁瑣)。

pandas的處理速度。為什麼不用mysql?  慢:文件操作慢;pandas:快在於將數據載入到記憶體了。

數據分析使用的庫:numpy作為依賴庫;pandas數據分析庫;matplotlib直觀的數據可視化庫;seaborn輔助庫(庫中含有調色板),圖形更加豐富;pyecharts:簡易的數據可視化庫,電商中比較常用;,,,。

pandas中有兩大數據類型。Series 級數(索引是有序的,一維的);DataFrame 結構化數據(二維的表)。

 

1. Series級數

Series是一種類似一維數組的數據結構,由一組數據和與之相關的index組成,即由values:一組數據(ndarray類型) 和 key:相關的數據索引標簽兩個部分組成。這個結構一看似乎與dict字典差不多,我們知道字典是一種無序的數據結構,而pandas中的Series的數據結構不一樣,它相當於定長有序的字典,並且它的index和value之間是獨立的,兩者的索引還是有區別的,Series的index變的,而dict字典的key值是不可變的。Series是將 序列 和 hash 融合在一起了。序列:索引有序,索引是枚舉類型;hash:鍵是無序的,鍵是關聯類型的。pandas中的兩大數據類型都可以使用對象和屬性的方式來獲取值和賦值,在pandas中,string也是object。

 

Series的創建 :

可由列表或numpy數組創建:預設索引為0到N-1的整數型索引。(list,tuple,dict,ndarry)強制轉換為Series類型 。

 1 # 由列表創建,預設索引為0到4的整數型索引
 2 s0 = Series([1,2,3,4,5])
 3 s0[1]   # 2
4 # 由numpy數組創建 5 s1 = Series(np.array(list('ABCD'))) 6 7 # 由字典(hash)創建,字典的key會被Series當作是index 8 s2 = Series({'A':1,"B":2,"C":3}) 9 10 # 通過設置index參數指定索引 --> {a:甲,b:乙,c:} 11 s3 = Series(data=list('甲乙丙丁'),index=list('abcd'))

 

Series的索引和切片:

1). 常規索引:可以使用中括弧取單個索引(此時返回的是元素類型),或者中括弧里一個列表取多個索引(此時返回的仍然是一個Series類型)。

2). 顯式索引:

- 使用index中的關聯類型作為索引值;- 使用.loc[](推薦)。可以理解為pandas是ndarray的升級版,但是Series也是dict的升級版

3). 隱式索引:
- 使用整數作為索引值;- 使用.iloc[](推薦)

1 # 常規索引
2 s3[0]           # ‘甲’
3 s3['a']        # ‘甲’​
4 
5 # 顯式索引
6 s3.loc['a']   # ‘甲’
7 8 # 隱式索引
9 s3.iloc[0]    # ‘甲’

4). 切片:

 1 # 常規切片,左閉右開
 2 s3[0:-1]
 3     # a    甲
 4     # b    乙
 5     # c    丙
 6     # Name: username, dtype: object
 7     
 8 # 顯式切片,全閉區間
 9 s3.loc['a':'d']
10     # a    甲
11     # b    乙
12     # c    丙
13     # d    丁
14     # Name: username, dtype: object
15     
16 # 隱式切片,左閉右開
17 s3.iloc[0:-1]
18     # a    甲
19     # b    乙
20     # c    丙
21     # Name: username, dtype: object

 

Series的屬性:

可以把Series看成一個定長的有序字典。

 1 '''
 2 ndim:維度
 3 shape:形狀
 4 size:獲取元素的長度
 5 dtype:數據類型
 6 index:獲取所有的索引
 7 values:獲取所有的值
 8 name:獲取名稱   
 9 head():快速查看Series對象的樣式,獲取前5條數據
10 tail():快速查看Series對象的樣式,獲取最後5條數據
11 '''

代碼演示示例:

 1 s3.shape      # (4,)
 2 s3.size       # 4
 3 s3.ndim       # 1
 4 s3.name       # 'username'
 5 s3.dtype      # dtype('O') 表示字元串類型
 6 s3.index      # Index(['a', 'b', 'c', 'd'], dtype='object')
 7 s3.keys()     # Index(['a', 'b', 'c', 'd'], dtype='object')
 8 s3.valuse     # array(['甲', '乙', '丙', '丁'], dtype=object)
 9 s3.head(n=5)
10 s3.tail(n=5)

 

檢測缺失數據:

當索引沒有對應的值時,可能出現缺失數據顯示NaN(not a number)的情況。註意:np.NaN  !==  np.NaN;可以使用pd.isnull(),pd.notnull(),或自帶isnull(),notnull()函數檢測缺失數據。

 1 # 造一含有NaN值的Series數據
 2 s5 = Series(data=range(4),index=list('abcd')) # NaN是float
 3 s5['c'] = np.nan        # 將索引c 的值變為nan  
 4 s5
 5   #  a    0.0
 6   #  b    1.0
 7   #  c    NaN
 8   #  d    3.0
 9   #  dtype: float64
10 
11 # 檢測缺失數據
12 cond = pd.isnull(s5)        # 相當於s5.isnull()
13 cond 
14   # a     False
15   # b     False
16   # c     True
17   # d     False
18   # dtype: bool
19 # 檢查到NaN值之後,將nan值的數據變成 0
20 s5[cond]= 0
21    # a    0.0
22    # b    1.0
23    # c    0.0
24    # d    3.0
25    # dtype: float64
26 
27 s5['c'] = np.nan    # 將索引c 的值變為nan  
28 
29 # 檢測缺失數據 
30 cond_fa = s5.notnull()     # 相當於pd.notnull(s5)
31 cond_fa
32    # a     True
33    # b     True
34    # c     False
35    # d     True
36    # dtype: bool
37 # 檢查到NaN值之後,將nan值篩選掉
38 s5[cond_fa]
39    # a    0.0
40    # b    1.0
41    # d    3.0
42    # dtype: float64 

 

Series之間的運算:

NaN+任何值都是NaN。在運算中自動對齊不同索引的數據,如果索引不對應,則補NaN。

 1 s5 * 3 
 2    # a    0.0
 3    # b    3.0
 4    # c    0.0
 5    # d    9.0
 6    # dtype: float64
 7 
 8 s6 = Series(range(5),list('bcdef'))
 9 
10 s5.add(s6)   # 相當於 s5+s6
11    # a    NaN
12    # b    1.0
13    # c    1.0
14    # d    5.0
15    # e    NaN
16    # f     NaN
17    # dtype: float64

 

2. DataFrame

DataFrame是一個【表格型】的數據結構,可以看做是【由Series組成的字典】(共用同一個索引)。DataFrame由按一定順序排列的多列數據組成。設計初衷是將Series的使用場景從一維拓展到多維。DataFrame既有行索引,也有列索引。行索引:index;列索引:columns;值:values(numpy的二維數組)。我們的 訓練集(一些二維的數據)都是二維的,那麼Series滿足不了這個條件,xy軸,軸上的一點(0,0)。DataFrame每一列可以是不同類型的值集合,所以DataFrame你也可以把它視為不同數據類型同一index的Series集合。

DataFrame的創建:

最常用的方法是傳遞一個字典來創建。DataFrame以字典的鍵作為每一【列】的名稱,以字典的值(一個數組)作為每一列的值。此外,DataFrame會自動加上每一行的索引(和Series一樣)。同Series一樣,若傳入的列與字典的鍵不匹配,則相應的值為NaN。

 1 df1 = DataFrame(data={'數學':[10,20,30,40,50],
 2                       '語文':[1,2,3,4,5],
 3                       '英語':[10,11,12,13,14]},
 4                 index=['Tom','Jhon','Jack','Marry','Jurray'],
 5                 columns=['英語','數學','語文'])
 6 
# 英語 數學 語文 7 # Tom 10 10 1 8 # Jhon 11 20 2 9 # Jack 12 30 3 10 # Marry 13 40 4 11 # Jurray 14 50 5

DataFrame屬性:

values、columns、index、shape、ndim、dtypes。

 1 # 行索引
 2 df1.index     # Index(['雷軍', '不知妻美', '不知爹富', '馬雲', '羅太軍'], dtype='object')
 3 
 4 # 列索引
 5 df1.columns   # Index(['英語', '數學', '語文'], dtype='object')
 6 
 7 df1.dtypes    
 8    # 英語    int64
 9    # 數學    int64
10    # 語文    int64
11    # dtype: object
12 
13 df1.size    # 15
14
df1.ndim # 2

DataFrame的索引:

1). 對列進行索引(獲取某一列): [ ] 預設只能取列索引- 通過類似字典的方式;- 通過屬性的方式。可以將DataFrame的列獲取為一個Series。返回的Series擁有原DataFrame相同的索引,且name屬性也已經設置好了,就是相應的列名。

df1['語文'] ---> 獲取‘語文’列

2). 對行進行索引(獲取某一行):- 使用.loc[]加index來進行行索引;- 使用.iloc[]加整數來進行行索引。同樣返回一個Series,index為原來的columns。

df1.loc['Tom'] ---> 獲取‘Tom’行
df1.iloc[0] ---> 獲取第0行,等於‘Tom’行

3). 對元素進行索引(獲取某一個元數/值):- 使用列索引;- 使用行索引(iloc[3,1]相當於兩個參數;iloc[[3,3]] 裡面的[3,3]看做一個參數);- 使用values屬性(二維numpy數組)

df1.loc['Tom','英語'] ---> 獲取‘Tom’行,‘英語’列的這個元素的值
df1.iloc[0,0]  ---> 獲取第0行,第0列的這個元素的值,和df1.loc['Tom','英語']結果一樣
 1 # 對列進行索引, [ ] 預設只能取列索引
 2 df1['語文']             # 獲取為一個Series  ,相當於【 df1.語文 】
 3 # Tom       1
 4 # Jhon      2
 5 # Jack      3
 6 # Marry     4
 7 # Jurray    5
 8 # Name: 語文, dtype: int64
 9 
10 df1.語文             # 不建議這樣獲取列
11 df1['Tom']             # 會報錯
12 
13 
14 # 對行進行索引
15 df1.loc['Tom']         # 顯式loc
16 # 英語    10
17 # 數學    10
18 # 語文     1
19 # Name: Tom, dtype: int64
20 
21 df1.iloc[0]            # 隱式iloc
22 # 英語    10 
23 # 數學    10
24 # 語文     1
25 # Name: Tom, dtype: int64
26 
27 # 對元素進行索引
28 df1.loc['Tom','英語']   # 10
29 
30 df1.iloc[0,0]         # 10

4). 切片操作:

獲取某些行和某些列的值,可以是多個值

 1 # 使用行索引顯式loc切片,全閉區間
 2 df1.loc['Tom':'Jack']                # 獲取Tom到Jack行的數據,針對行
 3 #       英語  數學  語文
 4 # Tom   10  10   1
 5 # Jhon  11  20   2
 6 # Jack  12  30   3
 7 
 8 df1.loc['Tom':'Jack','英語':'數學']   # 獲取Tom到Jack行,英語到數學列的數據
 9 #       英語  數學
10 # Tom   10  10
11 # Jhon  11  20
12 # Jack  12  30
13 
14 
15 # 使用行索引隱式iloc切片,左開右閉
16 df1.iloc[1:2]       # 獲取第1行到第2行的數據(不包含第2行),針對行
17 #       英語  數學  語文
18 # Jhon  11  20   2
19 
20 df1.iloc[0:2 , 0:2]  # 獲取第0行到第2行,第0列到第2列的數據(不包含第2行和第2列)
21 #       英語  數學
22 # Tom   10  10
23 # Jhon  11  20

 

DataFrame的運算:

Dataframe的運算同Series一樣。

下圖是Python 操作符與pandas操作函數的對應表:

 

 

Series與DataFrame之間的運算:

使用pandas操作函數:axis=0:以列為單位操作(參數必須是列),對所有列都有效;axis=1:以行為單位操作(參數必須是行),對所有行都有效。

列方向:df1.add(s)    #預設列相加;行方向:  (df1.T + s).T。

處理丟失的數據:
df1.loc['Tom','英語'] = np.NaN
df1.loc['Jack','數學'] = np.NaN

pandas 中對於空的操作:

isnull():是空值,notnull():不是空值,dropna() :過濾空值,fillna() :填充空值。

數據分析:刪除行比較合適,行代表的是一條數據,列會影響到所有的數據。機器學習:如果是行當中的空值比較多那就刪行,列中空值比較多就刪列。

 1 # 判斷是否為空值
 2 df1.loc[:,'英語'].isnull()
 3 # Tom       True
 4 # Jhon      True
 5 # Jack      True
 6 # Marry     True
 7 # Jurray    True
 8 # Name: 英語, dtype: bool
 9 
10 # 當該行中所有的元素都為空則刪除
11 df1.dropna(how='all')
12 13 # 當該行中所有的元素都為空則刪除
14 df1.dropna(how='any',axis=1,inplace=True)
15 
16 # 填充空值
17 df1.fillna(value=None, method=None, axis=None, inplace=False, limit=None, #downcast=None, **kwargs)

 

聚合操作:
所謂的聚合操作:平均數,標準方差,最大值,最小值……

1 df1.sum()        # 預設是對列進行操作
2 df1.mean()       # 預設是對列進行操作  
3 df1.max()        # 求列的最大值                                                          
4 df1.var()        # 樣本方差,表示的數據的波動性 
5 df1.std()        # 樣本標準差  

 

pandas的拼接操作:

pandas的拼接分為兩種:級聯:pd.concat, pd.append;合併:pd.merge, pd.join。

回顧numpy的級聯:

1 np.concatenate([np.random.randint(0,100,(5,4)),np.random.rand(5,4),np.random.randn(5,4)],axis=1)

1). 簡單級聯:

行合併:pd.concat([df1,df2],axis=0)。和np.concatenate一樣,優先增加行數(預設axis=0)。註意index在級聯時可以重覆。

 

列合併:pd.concat([df1,df2],axis=1)。不建議用,concat它不是聯表查詢,只擅長當union(垂直的 axis=0),水平合併一定不要用。

 

 1 # 垂直的內連接,join='inner' ,會刪除含有NaN的行或列
 2 pd.concat([df1,df2],axis=0,join='inner')   # index在級聯時可以重覆
 3 
 4 # 水平內連接
 5 pd.concat([df1,df2],axis=1,join='inner')
 6 
 7 # 外連接,不匹配的項補NaN
 8 pd.concat([df1,df2],axis=0,join='outer')
 9 
10 # ignore_index=True忽略重覆索引
11 pd.concat([df1,df2],axis=0,join='outer',ignore_index=True)
12 
13 # 使用多層索引 keys ,解決重覆問題
14 pd.concat([df1,df2],axis=0,join='outer',keys=['df1','df2'])
15          #   a   b   c
16    # df1 0  a0  b0  c0
17    #     1  a1  b1  c1
18    #     2  a2  b2  c2
19    # df2 2  a2  b2  c2
20    #     3  a3  b3  c3
21    #     4  a4  b4  c4

 

 2). 不匹配級聯:
不匹配指的是級聯的維度的索引不一致。例如縱向級聯時列索引不一致,橫向級聯時行索引不一致;有3種連接方式:
外連接:補NaN(預設模式)
內連接:只連接匹配的項
-連接指定軸 join_axes 顯示某一格dataframe 中的列

3).使用append()函數添加:

由於在後面級聯的使用非常普遍,因此有一個函數append專門用於在後面添加,append 和 concat 相似,只能直接做垂直:df1.append(df2)

 

 

 4). 使用pd.merge()合併:

merge與concat的區別在於,merge需要依據某一共同的行或列來進行合併,使用pd.merge()合併時,會自動根據兩者相同column名稱的那一列,作為key來進行合併。註意每一列元素的順序不要求一致

 

pd.merge(DataFrame1,DataFrame2, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=(’_x’, ‘_y’))

pd.merge(DataFrame1,DataFrame2) == DataFrame1.merge(DataFrame2)

參數:

how:預設為inner,可設為inner/outer/left/right
on:根據某個欄位進行連接,必須存在於兩個DateFrame中(若未同時存在,則需要分別使用left_on和right_on來設置)
left_on:左連接,以DataFrame1中用作連接鍵的列
right_on:右連接,以DataFrame2中用作連接鍵的列
left_index:將DataFrame1行索引用作連接鍵
right_index:將DataFrame2行索引用作連接鍵
sort:根據連接鍵對合併後的數據進行排列,預設為True
suffixes:對兩個數據集中出現的重覆列,新數據集中加上尾碼_x,_y進行區別

代碼演示區別:

 1 pd.DataFrame({'lkey':['foo','bar','baz','foo'], 'value':[1,2,3,4]})
 2 #   lkey  value
 3 # 0  foo      1
 4 # 1  bar      2
 5 # 2  baz      3
 6 # 3  foo      4
 7 
 8 pd.DataFrame({'rkey':['foo','bar','qux','bar'], 'value':[5,6,7,8]})
 9 #   rkey  value
10 # 0  foo      5
11 # 1  bar      6
12 # 2  qux      7
13 # 3  bar      8
14 
15 # inner鏈接
16 dataDf1.merge(dataDf2, left_on='lkey',right_on='rkey')
17 #   lkey  value_x rkey  value_y
18 # 0  foo        1  foo        5
19 # 1  foo        4  foo        5
20 # 2  bar        2  bar        6
21 # 3  bar        2  bar        8
22 
23 # Outer鏈接
24 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey', how='outer')
25 #   lkey  value_x rkey  value_y
26 # 0  foo      1.0  foo      5.0
27 # 1  foo      4.0  foo      5.0
28 # 2  bar      2.0  bar      6.0
29 # 3  bar      2.0  bar      8.0
30 # 4  baz      3.0  NaN      NaN
31 # 5  NaN      NaN  qux      7.0
32 
33 # left鏈接
34 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey',how='left')
35 #   lkey  value_x rkey  value_y
36 # 0  foo        1  foo      5.0
37 # 1  bar        2  bar      6.0
38 # 2  bar        2  bar      8.0
39 # 3  baz        3  NaN      NaN
40 # 4  foo        4  foo      5.0
41 
41 # right鏈接 42 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey',how='right') 43 # lkey value_x rkey value_y 44 # 0 foo 1.0 foo 5 45 # 1 foo 4.0 foo 5 46 # 2 bar 2.0 bar 6 47 # 3 bar 2.0 bar 8 48 # 4 NaN NaN qux 7

【註意】1).當有多個key相同時使用,使用on=顯式指定哪一列為key;當左右兩邊的key都不相等時,使用left_on和right_on指定左右兩邊的列作為key。

2).內合併:只保留兩者都有的key(預設模式);外合併 how='outer':補NaN;左合併、右合併:how='left',how='right'。

 

 

 

列衝突的解決:

 

 

當列衝突時,即有多個列名稱相同時,需要使用on=來指定哪一個列作為key,配合suffixes指定衝突列名,可以使用suffixes=自己指定尾碼。

1 dataDf1.merge(dataDf2, left_on='lkey', right_on='rkey', how='right', suffixes=('_df1', '_df2'))
2 #   lkey     value_df1  rkey  value_df2
3 # 0  foo        1.0      foo      5
4 # 1  foo        4.0      foo      5
5 # 2  bar        2.0      bar      6
6 # 3  bar        2.0      bar      8
7 # 4  NaN        NaN      qux      7

 

 

pandas刪除操作:

Dataframe.drop(labels=0,axis=0,inplace=True):labels=0表示 第0行 ,inplace=True表示對原數據 產生影響。

1 df1.drop(labels=0,axis=0,inplace=True)    # 刪除第0行
2 df1.drop(0)                               # 刪除第0行
3 df1.drop([0,1])                           # 刪除第0,1行

行重新設定:

Dataframe.set_index('id',inplace=True)

 1 dataDf1
 2 #   lkey  value
 3 # 0  foo      1
 4 # 1  bar      2
 5 # 2  baz      3
 6 # 3  foo      4
 7 
 8 dataDf1.set_index(['value'],inplace=True)  # 將'value'設置為index
 9 dataDf1
10 #        lkey
11 # value
12 #   1     foo
13 #   2     bar
14 #   3     baz
15 #   4     foo
16 
17 dataDf1.reset_index(inplace=True)          # 將index返回回dataframe中
18 dataDf1
19 #     value   lkey
20 #
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • RXEdior預設會有文件管理功能,但是靈活性需求不大,目前的設想是文件夾不允許修改,只允許增刪改文件。基於這樣的設想,把界面實現成這個效果: 這個功能並不是一個通用功能,並且我們做的代碼,也沒有按照類庫的標準要求,這種編輯功能實現有些複雜,用了大量的js事件,代碼不是很容易讀。後期這個功能可能會有 ...
  • 鷹眼插件 AMap.OverView 預設在地圖右下角顯示縮略圖 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>map</title> <script type="text/javascript" src= ...
  • 開始 今天和大家聊聊AOP:面向切麵編程思想。開始聊之前,先和大家一起從編程思想的發展說起。 編程思想的發展歷程: 1、POP編程 首先,大家應該都知道,什麼是POP編程吧,就是面向過程編程。關於這個編程思想就不做介紹了。 從思維上來講,面向過程更強調細節,忽視了整體性和邊界性。 典型代表是 C/C ...
  • 基礎準備: 8種基本數據類型包括4種整型,2種浮點型,1個字元型,1個布爾型 暫且稱呼為:(4211) 4種整型: byte short int long 2種浮點型:float double 1種字元型:char 1種布爾型:boolean 詳細分析: 基本數據類型和引用數據類型的區別: 基本數據 ...
  • 目的: 寂寞的夜晚總需要精神依托,用Python滋潤疲憊的身心!!! 效果: 實現類 1 from Common import Common 2 import requests 3 4 class Get_mn(Common): 5 """ 6 title:Python爬取成人網站圖片Demo 7 ...
  • 基於S2SH開發房屋租賃管理系統(前臺+後臺)開發環境: Windows操作系統開發工具:Myeclipse+Jdk+Tomcat+MYSQL資料庫運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.php?mod=viewthread&tid=102 ...
  • 基於S2SH開髮網上蛋糕店(甜品)購物商城系統(前臺+後臺) 開發環境: Windows操作系統開發工具:eclipse+Jdk1.8+Tomcat8+MySQL資料庫註意:請使用JDK1.8 Tomcat8版本運行運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.ph ...
  • 第一步:引入庫 import time import base64 import rsa import binascii import requests import re from PIL import Image import random from urllib.parse import qu ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...