pandas
<p style="font-size: 40px; text-align: center">pandas相关</p><p>pandas最常用的操作:索引、过滤、数据增删查改、分组聚合数据清理、合并、数据可视化</p>
<p>pandas常见命令操作</p>
<h2 id="1-dataframe筛选">1. dataframe筛选</h2>
<p>若需要从dataframe中的特定列筛选出特定值所在的行,其中特定列的数量是不确定的,每个特定列的特定值也是不同的,该如何处理?</p>
<pre><code class="language-python">import pandas as pd
# 创建示例数据
data = {'A': ,
'B': ,
'C': ,
'D': }
df = pd.DataFrame(data)
# 为不同列定义特定值
specific_values = {'A': 2, 'B': 6, 'C': 2, 'D': 6}
# 初始化筛选条件
filter_condition = pd.Series(True, index=df.index)
# 根据每列的要求分别处理
for col, value in specific_values.items():
filter_condition = filter_condition & (df == value)
# 应用筛选条件
filtered_df = df
print(filtered_df)
## 方法2,使用query
# 构造查询条件
query_string = ' & '.join()
# 使用query进行筛选
filter_df = df.query(query_string)
</code></pre>
<p>总结:</p>
<p><strong><code>query()</code></strong>方法适合快速筛选,对于简单的列值筛选,它的性能很好。</p>
<p><strong><code>np.all()</code></strong>是一个非常高效的方法,适用于需要筛选多个列的情况,通常比<code>apply()</code>等方法快。</p>
<p><strong><code>apply()</code></strong>方法适合于更加复杂的条件筛选,但它的性能较低,适合在不太关注性能的情况下使用。</p>
<p><strong><code>isin()</code></strong>方法在处理多个可选值时非常有效,但它不适用于范围比较的情况。</p>
<p>dataframe 筛选出排除特定几行的数据</p>
<h2 id="2-在dict中根据value找key">2. 在dict中根据value找key</h2>
<pre><code class="language-python">def find_keys_by_value(d, value):
keys =
return keys
</code></pre>
<h2 id="3-如何根据dataframe的groupby层级关系生成树可以使用图数据库后续探索一下">3. 如何根据dataframe的groupby层级关系,生成树。【可以使用图数据库,后续探索一下】</h2>
<p>若这个dataframe有两列值呢 ,value1 和value2,其余列不变</p>
<pre><code class="language-python">import pandas as pd
# 示例 DataFrame
data = {
'Level1': ['A', 'A', 'A', 'B', 'B', 'C'],
'Level2': ['X', 'Y', 'Y', 'Z', 'Z', 'X'],
'Level3': ['M', 'N', 'O', 'P', 'Q', 'R'],
'Value1': ,
'Value2':
}
df = pd.DataFrame(data)
# 定义构建树的递归函数
def build_tree(df, group_cols, value_cols):
if len(group_cols) == 0:
return df.to_dict('records')
current_col = group_cols
grouped = df.groupby(current_col)
tree = {}
for name, group in grouped:
tree = build_tree(group, group_cols, value_cols)
return tree
# 构建树
group_cols = ['Level1', 'Level2', 'Level3']
value_cols = ['Value1', 'Value2']
tree = build_tree(df, group_cols, value_cols)
</code></pre>
<h2 id="4-dataframe中特定的两列按照某个函数的计算规则将所有行计算一遍生成新的数存在dataframe的新列中">4. dataframe中,特定的两列按照某个函数的计算规则,将所有行计算一遍,生成新的数,存在dataframe的新列中。</h2>
<pre><code class="language-python">import pandas as pd
# Create an example DataFrame
data = {'A': ,
'B': }
df = pd.DataFrame(data)
# Define a custom function to apply to the two columns
def custom_function(x, y):
return x + y * 2# Example function: add column A with twice the value of column B
# Apply the custom function to the two columns and create a new column 'C'
df['C'] = df.apply(lambda row: custom_function(row['A'], row['B']), axis=1)
# Display the updated DataFrame
print(df)
</code></pre>
<table>
<thead>
<tr>
<th>方法</th>
<th>适用对象</th>
<th>作用范围</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>apply</code></td>
<td>DataFrame / Series</td>
<td>对列、行或元素应用函数</td>
<td>对每列或每行应用函数<br>axis=0 或 默认值:对每列操作。<br>axis=1:对每行操作</td>
</tr>
<tr>
<td><code>applymap</code></td>
<td>DataFrame</td>
<td>对 DataFrame 每个元素应用函数</td>
<td>对 DataFrame 中每个元素应用函数</td>
</tr>
<tr>
<td><code>map</code></td>
<td>Series</td>
<td>对 Series 的每个元素应用函数</td>
<td>替换或映射 Series 中的每个元素</td>
</tr>
<tr>
<td><code>transform</code></td>
<td>DataFrame / Series</td>
<td>对 Series 或 DataFrame 应用元素级转换</td>
<td>对 Series 或 DataFrame 中的每个元素进行转换,通常保持原数据形状</td>
</tr>
</tbody>
</table>
<h2 id="5-pdexcelwriter">5. pd.ExcelWriter</h2>
<p>将多个dataframe写入EXcel文件的不同sheet</p>
<h2 id="6-数据切片">6. 数据切片</h2>
<pre><code class="language-python">data.iloc#前面是行,后面是列
有如下形式的切片
cols = list(range(7, 103)) + list(range(107, data.shape))
data.iloc
</code></pre>
<h2 id="7-df去重">7. df去重</h2>
<p>去重函数</p>
<pre><code class="language-python">import pandas as pd
dict={'x':,'y':,'z':}
df=pd.DataFrame(dict)
## subset可以指定重复的列,进行去重
df.drop_duplicates(subset=['y','z'],keep='first',inplace=True)
</code></pre>
<h2 id="8-按照时间排序">8. 按照时间排序</h2>
<p>weekofyear_sum中'year'列确实存在重复的值以便触发第二列 'weekofyear'的排序</p>
<pre><code class="language-python">data_group.sort_values(by='data_date')
# 同时对两列值排序 True是升序
weekofyear_sum.sort_values(by=['year', 'weekofyear'], ascending=, inplace=True)
</code></pre>
<h2 id="9-shift函数">9. shift函数</h2>
<p>实现对每一天中的<strong>相邻行批次号不同的个数</strong>的聚合,并且最后得到整段时间内的平均每天相邻行批次号不同的个数</p>
<pre><code class="language-python">import pandas as pd
# 示例数据
data = {
'datetime_column': pd.to_datetime(['2025-03-20', '2025-03-20', '2025-03-21', '2025-03-21', '2025-03-22']),
'工序名称': ['A', 'A', 'B', 'B', 'A'],
'工序代码': ,
'工单ID': ,
'批次号': ['B123', 'B123', 'B456', 'B456', 'B123'],
'物资编码': ['M001', 'M002', 'M003', 'M004', 'M005'],
'过数智能单元': ['X', 'X', 'Y', 'Y', 'X']
}
# 创建 DataFrame
df = pd.DataFrame(data)
# 定义 sub_select 函数进行按日期分组聚合
def sub_select(df):
# 按日期分组
df['日期'] = df['datetime_column'].dt.date# 提取日期部分(去掉时间)
# 计算每一天中相邻行批次号不同的个数
df['批次号不同'] = (df['批次号'] != df['批次号'].shift()).astype(int)
# 按日期分组并计算每一天批次号不同的个数
daily_diff_counts = df.groupby('日期')['批次号不同'].sum()
# 计算所有天的平均批次号不同的个数
average_daily_diff = daily_diff_counts.mean()
return average_daily_diff
# 计算分组后的结果
result = df.groupby(['工序名称', '工序代码', '过数智能单元']).apply(sub_select)
# 打印结果
print(result)
</code></pre>
<h2 id="10-筛选">10. 筛选</h2>
<h3 id="101-某一列中特定值进行筛选">10.1. 某一列中特定值进行筛选</h3>
<pre><code class="language-python"># 筛选出某列是特定值的行
data == "taget1"]
# 筛选出某列是特定值的行,此特定值包含多种情况
lines = ["a", "b", "c"]
data = data.isin(lines)]
</code></pre>
<h3 id="102-某多列中特定值进行筛选">10.2. 某多列中特定值进行筛选</h3>
<pre><code class="language-python">import pandas as pd
# 新建dataframe
df1 = pd.DataFrame{{
"A":,
"B":['A', 'B', 'C', 'D],
"C":['X', 'Y', 'Z', 'W'],
"D":
}}
filter_series = pd.Series{{
"C": 30,
"B": "A"
}}
#映射字典
column_mapping = {
"C" : "A",
}
filter_df = df1 == val for col, val in filter_series.item()), axis = 1)]
</code></pre>
<h2 id="11-排序">11. 排序</h2>
<h2 id="12-分组">12. 分组</h2>
<pre><code class="language-python"># 按某一列分组
after_gb = df.groupby("col_name")
分组之后可以将group类型转为list类型进行查看
after_gb_list = list(after_gb)
list之后的数据结构是元组形式,元组中包含col_name也包含dataframe
for name, data in after_df:
print(name)
print(data) # 遍历出来的data是dataframe的数据格式
after_df.sum() # 分组之后的聚合操作
after_df.mean() # 分组
after_df["col_name"].transform("sum") # 将求和结果分到每一行上,返回series
过滤:删除某些行
例如:
after_df.filter(lambda x: x["销量"].sum() > 6)
</code></pre>
<h2 id="13-拼接">13. 拼接</h2>
<p>拼接用法</p>
<p>官方文档指南</p>
<p> dataframe的拼接有四个函数可以使用,分别是merge、join、concat、compare,其中文含义分别是合并、连接、串联、对比。</p>
<h3 id="131-concatenate-串联concat函数">13.1. concatenate-串联(concat函数)</h3>
<p>concat函数中axis的用法</p>
<p>concat函数参数介绍及用法代码示例</p>
<p> concat默认是按轴拼接,轴的意思是行index。即默认参数axis = 0。</p>
<pre><code class="language-python"># concat函数(上下拼接)
df = pd.concat(objs, axis = 0, ignore_index = False, join = "outer")
# objs: 指的是要合并的dataframe(们)。可以是一个列表也可以是一个集合(df1,df2,...)
# axis:dataframe拼接的方向。默认axis=0,上下拼接;设置axis=1,左右拼接
# ignore_index:是否需要重新设置索引,默认是False
# join:默认join = "outer",非交集用nan填。若join = "inner",显示交集
</code></pre>
<p>两个单列dataframe想进行上下拼接,并拼接成单列时,需要注意列名必须一样。</p>
<pre><code class="language-python">s1 = pd.Series(['a', 'b', 'c'], index=)
s2 = pd.Series(['d', 'e', 'f'], index=)
s1df = s1.to_frame(name='值')
s2df = s2.to_frame(name='值3')
s12 = pd.concat()
print(s12)
# 值 值3
# 0 aNaN
# 1 bNaN
# 2 cNaN
# 0NaN d
# 1NaN e
# 2NaN f
# 创建两个示例 DataFrame,包含相同的列名
df1 = pd.DataFrame({
'A': ,
'B':
})
df2 = pd.DataFrame({
'A': ,
'B':
})
# 使用 pd.concat 进行横向拼接
result = pd.concat(, axis=1)
# 打印结果
print(result)
# ABA B
#014710
#125811
#236912
</code></pre>
<h3 id="132-merge">13.2. merge</h3>
<p>pandas.DataFrame.merge() 参数详解</p>
<p> 是使用数据库风格的连接合并DataFrame或已命名的系列对象</p>
<pre><code class="language-python">DataFrame.merge(left, 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)
# 关键参数为left_df,right_df、how、on
# how有 {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘inner’ 默认为合并两个frame的交集
# on表示连接时,参考的主键。可以是一个,也可以是多个。
</code></pre>
<p>如果基于两边的索引合并,使用 left_index=True 和 right_index=True</p>
<h3 id="133-左连接时发现左边表格行数变多是什么原因导致的">13.3. 左连接时,发现左边表格行数变多,是什么原因导致的。</h3>
<p>右边表格有重复的行: 在左连接中,左表的每一行会与右表中满足连接条件的行进行匹配。如果右表中某个值出现了多次,那么左表中相应的每一行都会与右表中的每一匹配行进行组合,从而导致左表的行数增加。</p>
<ol>
<li>
<p><strong>右边表格有重复的行</strong>:</p>
<p><strong>例如</strong>:</p>
<ul>
<li>左表(A):
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Tom</td>
</tr>
<tr>
<td>2</td>
<td>Jerry</td>
</tr>
</tbody>
</table>
</li>
<li>右表(B):
<table>
<thead>
<tr>
<th>ID</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>90</td>
</tr>
<tr>
<td>1</td>
<td>85</td>
</tr>
<tr>
<td>2</td>
<td>88</td>
</tr>
</tbody>
</table>
</li>
</ul>
<p>当你对这两个表进行左连接时,左表的行数会增加,因为 ID 为 1 的行在右表中有两条记录,结果如下:</p>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Tom</td>
<td>90</td>
</tr>
<tr>
<td>1</td>
<td>Tom</td>
<td>85</td>
</tr>
<tr>
<td>2</td>
<td>Jerry</td>
<td>88</td>
</tr>
</tbody>
</table>
<p>这里,ID 为 1 的行出现了两次。</p>
</li>
</ol>
<p><strong>解决办法</strong>:</p>
<ul>
<li>可以通过检查右表是否有重复行来避免这一问题,或者使用 <code>DISTINCT</code> 语句来去除重复项。</li>
<li>如果不希望某些行重复,可以通过调整连接条件或使用合适的<strong>聚合函数</strong>来控制重复数据。</li>
</ul>
<h2 id="14-dataframe转ndarrayndarray转dataframe">14. dataframe转ndarray、ndarray转dataframe</h2>
<pre><code class="language-python">df.values
pd.dataframe(ndarray)
</code></pre>
<h2 id="15-增加多列">15. 增加多列</h2>
<p>pandas dataframe 新增单列和多列</p>
<pre><code class="language-python"> df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([], index=df.index)
</code></pre>
<h2 id="16-修改列名">16. 修改列名</h2>
<p>pandas DataFrame数据重命名列名的几种方式</p>
<h3 id="161-删除指定行">16.1. 删除指定行</h3>
<pre><code class="language-python">obj_cols = ["data_date", "destination_country", "service_level_name", "goods_type_name"]
df_dropped = i_df_T.drop(index=obj_cols) # 删除行名为obj_cols的行
</code></pre>
<h2 id="17-输出为excel">17. 输出为excel</h2>
<pre><code class="language-python">import pandas as pd
# 创建一个示例 DataFrame
data = {'A': , 'B': }
df = pd.DataFrame(data)
# 输出为 Excel 文件,不包含索引
df.to_excel('df.xlsx', index=False)
</code></pre><br><br>
来源:https://www.cnblogs.com/systemTang/p/18949023
頁:
[1]