r = {'A': {'B': C}}转为DataFrame
时间: 2024-11-13 19:18:02 浏览: 26
当你有一个像 `r = {'A': {'B': C}}` 这样的字典结构,其中嵌套了更深层次的键值对,想要将其转换为 DataFrame(数据框),你需要先将这个嵌套字典扁平化。在Python的pandas库中,这通常涉及到两步操作:
1. 将字典迭代并收集所有需要的列名和对应的值列表。
2. 使用 `pd.DataFrame()` 函数创建 DataFrame。
下面是一个简单的示例代码片段:
```python
import pandas as pd
# 假设 C 是一个列表或其他可以转换为一维数组的数据
C_values = [value for sublist in r.values() for value in sublist.values()]
column_names = list(r.keys())
data = {key: [val] for key, val in zip(column_names, C_values)}
df = pd.DataFrame(data)
# 如果C是一个二维数组,可能还需要额外处理
# df = pd.DataFrame(C, index=[k for k in r.keys()])
```
现在 `df` 就是基于给定字典 `r` 创建的 DataFrame。
相关问题
[V_M_CH,V_M_DCH,A_M_CH,A_M_DCH,T_M_CH,T_M_DCH,A_CH_CH,A_CH_DCH,V_CH_CH,V_CH_DCH,t_CH,t_DCH,C,S_A,B_A,Ar,B_R,R_R,Re,Rct]=getdata(B0005,616); 将获得的数据转为表格形式存储
您可以使用以下代码将获得的数据转换为表格形式存储:
```python
import pandas as pd
data = {'V_M_CH': V_M_CH,
'V_M_DCH': V_M_DCH,
'A_M_CH': A_M_CH,
'A_M_DCH': A_M_DCH,
'T_M_CH': T_M_CH,
'T_M_DCH': T_M_DCH,
'A_CH_CH': A_CH_CH,
'A_CH_DCH': A_CH_DCH,
'V_CH_CH': V_CH_CH,
'V_CH_DCH': V_CH_DCH,
't_CH': t_CH,
't_DCH': t_DCH,
'C': C,
'S_A': S_A,
'B_A': B_A,
'Ar': Ar,
'B_R': B_R,
'R_R': R_R,
'Re': Re,
'Rct': Rct}
df = pd.DataFrame(data)
```
其中,`V_M_CH`、`V_M_DCH`、`A_M_CH`、`A_M_DCH`、`T_M_CH`、`T_M_DCH`、`A_CH_CH`、`A_CH_DCH`、`V_CH_CH`、`V_CH_DCH`、`t_CH`、`t_DCH`、`C`、`S_A`、`B_A`、`Ar`、`B_R`、`R_R`、`Re`、`Rct` 是您在 `getdata()` 函数中获取的数据。`df` 是转换后的表格形式数据。
``` import pandas as pd import matplotlib.pyplot as plt data1 = pd.read_excel(r"C:\Users\tengh\Desktop\3\农排灌溉、煤改电\煤改电\一般台区(200户以上)类型台区晋中市21年12月29日-22年01月05日96点数据鼓楼变采集点\煤改电用户功率.xlsx", parse_dates=["数据日期"]) data2 = pd.read_excel(r"C:\Users\tengh\Desktop\3\农排灌溉、煤改电\煤改电\一般台区(200户以上)类型台区晋中市21年12月29日-22年01月05日96点数据鼓楼变采集点\乡村居民生活用电功率.xlsx", parse_dates=["数据日期"]) # 筛选用户并处理数据类型 user1 = data1[data1["用户/台区名称"] == "程玉林(煤改电)"] user2 = data2[data2["用户/台区名称"] == "胡晋雅"] # 预处理:确保数值类型 time_columns = user1.columns[8:-1] user1[time_columns] = user1[time_columns].apply(pd.to_numeric, errors='coerce').fillna(0) user2[time_columns] = user2[time_columns].apply(pd.to_numeric, errors='coerce').fillna(0) # 合并数据 combined = ( user1.set_index("数据日期")[time_columns] .add(user2.set_index("数据日期")[time_columns], fill_value=0) .groupby(level=0).sum() ) # 绘图设置 plt.figure(figsize=(15, 8)) for date in combined.index.unique(): daily_data = combined.loc[date] plt.plot( daily_data.values.astype(float), label=date.strftime("%Y-%m-%d") ) # 以下坐标设置保持不变 plt.xlabel("时间点(15分钟间隔)") plt.ylabel("总有功功率(kW)") plt.title("7×24小时功率叠加图") plt.xticks( range(0, 96, 4), [f"{i//4}:{i%4*15:02d}" for i in range(0, 96, 4)], rotation=45 ) plt.legend() plt.grid() plt.tight_layout() plt.show()```所有天数的数据合并成一条线,即所有时间点连起来。如果数据是7天,每天96点,合并后变成7*96=672点,横坐标可能需要调整。
<think>好的,我需要帮助用户修改他们的Python代码,将7天的数据合并成一条连续的线,总共672个数据点,并调整横坐标。让我先仔细看一下用户提供的代码和需求。
首先,用户的数据是每天96个时间点,共7天。当前的代码是将每一天的数据单独绘制成一条线,导致图中有7条线,每条96个点。用户希望将这些数据合并成一条连续的线,即7天×96点=672点,同时调整横坐标显示正确的时间。
用户提供的代码中,合并数据使用了`groupby`按日期求和,这可能是在每天同一时间点的值相加,但用户实际需要的是将不同日期的数据按时间顺序连接起来。这可能是一个误解。正确的合并应该是将多天的数据按时间顺序拼接,而不是按时间点求和。
接下来,我需要检查数据合并的部分。当前的`combined`变量是通过`add`和`groupby`得到的,这可能是在每个时间点上将两个用户的数据相加,然后按日期分组求和。但用户的需求是将不同日期的数据按顺序连接,形成一条长的时间序列。因此,应该使用`pd.concat`来按行拼接数据,而不是按列相加。
然后,绘图部分需要调整。原代码循环遍历每一天,绘制当天的96个点。修改后应该直接绘制所有合并后的数据点,即672个点。同时,横坐标需要从0到671,每个点代表15分钟间隔。但用户可能需要横坐标显示实际的时间,比如从第一天0:00到第七天23:45,每隔15分钟一个点。
另外,横坐标的标签需要调整。原代码每4个点显示一次,即每小时显示一次。对于672个点,可能需要每隔一定数量的点显示日期和时间,避免标签过于密集。例如,每24小时(96点)标记一次日期,或者每6小时显示一次时间。
还需要处理数据类型,确保拼接后的数据是正确的数值类型,并且时间顺序正确。可能需要将日期和时间点合并成一个时间索引,以便正确绘制连续的时间序列。
总结修改步骤:
1. 合并数据时,按日期顺序拼接每一天的96个点,形成672点的连续数据。
2. 调整绘图代码,一次性绘制所有672个点,而不是每天一条线。
3. 重新设置横坐标标签,反映连续的时间跨度,可能需要使用日期时间格式而不是简单的小时数。
4. 可能需要生成新的时间索引,将各天的数据按实际日期和时间连接起来,以确保横坐标正确显示。
现在,我需要检查用户的数据结构。假设每个用户的DataFrame中,每一行代表一个日期,列是时间点(如00:15, 00:30等)。合并时,应该将每个日期的所有时间点转换为一个长序列,按日期顺序排列。
例如,对于用户1和用户2的数据,每个日期有96个点。合并后的数据应该是每个日期的时间点按顺序连接,并且每个时间点加上对应的用户数据。然后,将所有日期的数据按顺序拼接成一个长序列。
因此,正确的合并方法可能是将每个用户的数据转换为长格式,按时间排序,然后相加,最后拼接所有日期的数据。
这可能涉及到数据重塑,使用`melt`函数将列转换为行,然后按时间排序。或者,将每个日期的96个点转换为一个时间序列,并按日期顺序排列。
此外,需要确保数据在合并时没有重叠或缺失的日期,否则时间索引可能不连续。
修改后的代码可能需要:
1. 对每个用户的数据进行重塑,生成日期和时间的多级索引。
2. 将两个用户的数据按时间索引相加。
3. 按日期和时间顺序拼接所有天的数据。
4. 绘图时使用新的连续时间索引作为横坐标,并调整标签显示。
可能需要使用`pd.melt`来将宽表转换为长表,或者使用`stack`方法。例如,将每个日期的96列转换为96行,每个行对应一个时间点,然后按日期和时间排序。
例如,对于user1和user2,处理步骤如下:
- 设置索引为“数据日期”,然后堆叠(stack)时间列,得到一个多级索引(日期,时间点)的Series。
- 将两个用户的Series相加(注意处理缺失值)。
- 重置索引并排序,得到按日期和时间点排列的长格式数据。
- 拼接所有7天的数据,形成672个点。
然后,绘图时直接绘制所有点,横坐标使用生成的时间序列或对应的索引,并调整标签显示。
这可能涉及到生成正确的时间戳,例如,将每个日期的时间点(如00:15, 00:30等)转换为实际的datetime对象,然后按顺序排列所有时间戳,形成连续的672个点。
这样,横坐标就可以正确显示为从第一天开始到第七天结束的连续时间,每个点间隔15分钟。
最后,调整横坐标的刻度标签,可能每隔一定时间显示日期和时刻,以避免过于密集。
现在,我需要将这些步骤转化为代码修改。例如:
1. 重塑每个用户的数据为长格式,包含日期、时间点和功率值。
2. 合并两个用户的数据,按日期和时间点相加。
3. 按日期和时间点排序,形成连续的时间序列。
4. 绘图时使用索引作为x轴,或者生成连续的时间标签。
具体代码可能如下:
对于user1和user2,处理每个用户的数据:
```python
# 将每个用户的数据转换为长格式
def process_user_data(user_data):
# 假设时间列是user_data.columns[8:-1],即从第8列到倒数第二列
time_cols = user_data.columns[8:-1]
# 将数据日期作为索引,然后堆叠时间列
df = user_data.set_index("数据日期")[time_cols].stack().reset_index()
df.columns = ["数据日期", "时间点", "功率"]
# 将时间点转换为timedelta
# 假设时间点格式为"HH:MM",如"00:15"
df["时间"] = pd.to_timedelta(df["时间点"] + ":00")
# 创建完整的datetime
df["时间戳"] = df["数据日期"] + df["时间"]
return df.set_index("时间戳")["功率"]
# 处理两个用户的数据
user1_series = process_user_data(user1)
user2_series = process_user_data(user2)
# 合并数据,相加并填充0
combined_series = user1_series.add(user2_series, fill_value=0)
# 按时间戳排序
combined_series = combined_series.sort_index()
```
然后,绘图:
```python
plt.figure(figsize=(15, 8))
plt.plot(combined_series.index, combined_series.values, label="总有功功率")
# 设置横坐标标签
plt.xlabel("时间")
plt.ylabel("总有功功率(kW)")
plt.title("7×24小时功率叠加图(连续)")
# 调整横坐标刻度,例如每24小时显示一次日期
plt.xticks(rotation=45)
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%m-%d %H:%M"))
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=1)) # 每天一个刻度
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
```
但用户原来的数据可能时间列不是"HH:MM"格式,而是类似列名为"0"到"95"代表时间点。例如,每个列名代表15分钟间隔,如0代表00:00,1代表00:15,依此类推。这种情况下,需要将列名转换为时间偏移。
例如,假设时间列是0到95,每个代表15分钟间隔,从00:00开始:
```python
def process_user_data(user_data):
time_cols = user_data.columns[8:-1] # 假设这些是0到95的字符串
# 转换为整数
time_points = pd.to_numeric(time_cols)
# 将数据日期作为索引,然后堆叠时间列
df = user_data.set_index("数据日期")[time_cols].stack().reset_index()
df.columns = ["数据日期", "时间点", "功率"]
df["时间点"] = pd.to_numeric(df["时间点"])
# 转换为timedelta:每个时间点*15分钟
df["时间偏移"] = pd.to_timedelta(df["时间点"] * 15, unit='m')
df["时间戳"] = df["数据日期"] + df["时间偏移"]
return df.set_index("时间戳")["功率"]
```
这样,每个时间点列(如0,1,...,95)会被转换为相对于数据日期的具体时间戳,例如数据日期是2021-12-29,时间点0对应2021-12-29 00:00:00,时间点1对应00:15:00,依此类推。
然后,合并后的series将包含从第一天00:00到第七天23:45的所有时间点,共7×96=672个点,按时间顺序排列。
这样绘图时,x轴将使用实际的时间戳,matplotlib会自动处理日期的显示,但可能需要调整刻度格式,使其更易读。
用户原来的代码中,横坐标是使用0-95的索引,并转换为小时:分钟。但合并后需要显示实际日期和时间。因此,使用时间戳作为x轴,并设置合适的刻度格式会更合适。
总结修改步骤:
1. 重塑每个用户的数据,将每个时间点转换为具体的时间戳。
2. 合并两个用户的数据,按时间戳相加。
3. 按时间戳排序,形成连续的时间序列。
4. 绘图时使用时间戳作为x轴,调整刻度格式显示日期和时间。
这样,用户的数据将被正确合并为一条连续的线,横坐标显示实际的时间,共672个点。</think>我理解了你的需求:需要将7天数据按时间顺序拼接成一条连续曲线(共672个点),并调整横坐标显示时间跨度。以下是修改建议:
```python
# ... 前面数据读取和用户筛选部分保持不变 ...
# 预处理函数:将单日96点数据转换为时间序列
def preprocess(user_data):
# 提取时间点列(假设列名格式为字符串形式的0-95)
time_points = user_data.columns[8:-1].astype(int)
# 转换为长格式
melted = user_data.melt(
id_vars=["数据日期"],
value_vars=time_points.astype(str),
var_name="时间点",
value_name="功率"
)
# 生成精确时间戳(每15分钟间隔)
melted["时间点"] = melted["时间点"].astype(int)
melted["时间戳"] = melted["数据日期"] + pd.to_timedelta(melted["时间点"]*15, unit="m")
return melted.set_index("时间戳")["功率"]
# 处理两个用户数据
ts1 = preprocess(user1)
ts2 = preprocess(user2)
# 合并时间序列(相同时间点功率相加)
combined = ts1.add(ts2, fill_value=0).sort_index()
# 绘图
plt.figure(figsize=(20, 8))
plt.plot(combined.index, combined.values, linewidth=1)
# 设置坐标轴
plt.xlabel("时间")
plt.ylabel("总有功功率(kW)")
plt.title("连续7天功率变化曲线(672个时间点)")
# 配置时间刻度
ax = plt.gca()
ax.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d %H:%M")) # 显示月-日 时:分
ax.xaxis.set_major_locator(mdates.AutoDateLocator()) # 自动选择刻度间隔
plt.xticks(rotation=35)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
```
修改亮点说明(使用$$...$$格式展示关键公式):
1. **数据重组**:
通过`melt()`将宽表转为长表,建立时间序列:
$$ \text{原始矩阵} \xrightarrow{\text{melt}} \begin{bmatrix} \text{日期} & \text{时间点} & \text{功率} \end{bmatrix} $$
2. **时间戳生成**:
计算精确时间位置:
$$ t_{\text{精确}} = t_{\text{日期}} + n \times 15\text{min} \quad (n=0,1,...,95) $$
3. **功率叠加**:
使用矢量相加处理时间序列:
$$ P_{\text{总}}(t) = P_{\text{煤改电}}(t) + P_{\text{生活用电}}(t) $$
4. **可视化优化**:
- 自动选择时间刻度间隔
- 显示完整日期时间格式
- 672个数据点连续绘制
最终输出将呈现完整的连续曲线,横轴显示真实时间信息(如`12-29 00:00`到`01-05 23:45`),纵轴显示叠加后的总有功功率值。
阅读全文
相关推荐
















