自定义函数之数字后移

博主后天机试,找题目练习。题目要求将n个整数顺序向后移m个位置,最后m个数变成前面m个数。介绍可将其抽象成循环过程,把需要转移的数据后移,超出部分放最前。还给出代码注意事项,如申请空间要大、数组循环时注意+1或 -1。

后天机试,找几个题目练练手。

题目描述
有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数。写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数。
输入
输入数据的个数n n个整数 移动的位置m
输出
移动后的n个数
样例输入
10
1 2 3 4 5 6 7 8 9 10
2
样例输出
9 10 1 2 3 4 5 6 7 8

思路清晰的话很容易的

很显然这可以抽象成一个循环的过程,即数组种的最后一个跑到了数组的最前面,然后就形成了一个循环。A→B→C→D→A,所以我们只需要将需要转移的数据向后移动就可以了,然后再把超出部分放到最前面即可完成。表述不清出的话,看代码注释部分吧。

注意事项:申请的空间尽可能的大,不然数据如果过大的话会放不下
/*摘自某dalao思路 */

代码:

#include<stdio.h>

void fun(int a[100],int n,int j)
{
	int k;
	k=n;
	for(n=n-1;n>=0;n--)
	{
		a[n+j]=a[n];
	}

	for(j=j-1;j>=0;j--)
		a[j]=a[k+j];


}

int main()
{
	int a[100],n,j,i,b[100];
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	scanf("%d",&j);
	
	fun(a,n,j);

	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	return 0;
}

注意事项:
注意数组循环的时候,对应的+1还是-1!!!!!!
因为数组以0开头,很鸡儿麻烦。

<think>我们计划封装一个函数,该函数的功能是在DataFrame的指定位置插入一行,同时保持原始索引不变。输入参数包括:df:要操作的DataFramerow_data:要插入的新行数据(可以是一个字典、Series或列表等,但需要能转换成DataFrame的一行)insert_position:插入的位置(整数,从0开始,表示插入到该位置之后?或者之?这里需要明确)new_index:新行的索引标签(可选,如果不提供,则可能需要生成一个唯一的索引,但用户可能希望自定义索引)根据之的思路,我们将使用pd.concat方法,将原DataFrame分成两部分,然后在中间插入新行。注意:我们明确插入位置是按行号(位置)而不是按索引标签。因为按索引标签插入可能会在非连续索引中遇到问题。函数设计:definsert_row(df,row_data,insert_position,new_index=None):#如果new_index未提供,则生成一个唯一索引(例如,当最大索引+1,但要注意索引类型可能是字符串或整数等)#但更通用的做法是让用户指定,因为索引类型多样,自动生成可能不总是合适。步骤:1.将新行数据转换为一个单行的DataFrame,并指定索引(使用new_index)。2.将原DataFrame按位置分割成两部分:从0到insert_position(包括insert_position行)和insert_position+1到最后。但是注意:我们的插入位置是指定位置(行号)之后插入,还是之?通常,我们可能希望插入在指定位置的行之后?例如,insert_position=0,表示插入在第0行之后(即第1行位置)?或者插入在第0行之(即变成新的第0行)?这里我们需要明确:insert_position表示新行插入后的位置索引(即插入后新行所在的行号)。例如:插入位置0:新行成为第0行,原来的第0行变成第1行,以此类推。插入位置1:新行成为第1行,原来的第1行及以后的行都后移。但是,按照之我们的示例,我们使用insert_position=1(即第1行之后插入),那么实际上我们是将原DataFrame切成两部分:第一部分:原df的第0行到第0行(即第0行,因为切片是左闭右开,所以df.iloc[:1]包含第0行)第二部分:原df的第1行到最后(即df.iloc[1:])然后在中间插入新行。因此,如果我们希望新行插入后成为第k行(即行号为k),那么我们应该在k位置之插入,即:将原DataFrame切分为:k行(即0到k-1行)和从k行到最后,然后在中间插入新行。所以,我们可以这样定义:insert_position表示新行要插入的位置(行号),即插入后新行的行号。那么:df_new=pd.concat([df.iloc[:insert_position],new_row,df.iloc[insert_position:]])例如:原始行索引位置:0,1,2如果insert_position=0,则新行成为第0行,原第0行变成第1行。如果insert_position=1,则新行成为第1行,原第1行变成第2行,原第2行变成第3行。如果insert_position=3(即最后),则新行成为最后一行。注意:insert_position的取值范围应该是0到len(df)(包括len(df)),当insert_position等于len(df)时,就是在最后追加。但是,如果insert_position大于len(df)怎么办?我们可以将其限制为len(df),即如果超过最大行号,就插入到最后。另外,新行的索引需要唯一吗?虽然pandas允许重复索引,但通常建议唯一。所以我们要求用户传入new_index,或者由函数生成一个唯一的索引(但生成方式需要根据原索引类型)。生成唯一索引的简单方法:如果原索引是整数类型,可以取当最大索引+1(但注意,如果原索引不是连续的,这样可能重复?)所以更安全的方法是生成一个未使用过的整数索引,例如max_index+1,或者使用uuid字符串等。但考虑到通用性,我们让用户自己传入索引标签,因为用户可能知道如何生成合适的索引。如果用户没有传入,我们可以抛出一个错误,或者尝试生成一个唯一的字符串索引(例如使用uuid)。这里我们提供两种选择:选项1:强制用户传入new_index(这样更安全,避免索引冲突)选项2:如果用户没有传入,则生成一个唯一的索引,例如:'new_row_'+str(len(df)),并检查是否唯一,如果不唯一则追加数字直到唯一。但为了简单和避免复杂逻辑,我们选择要求用户传入new_index,因为索引标签的含义由用户决定。因此,函数定义如下:另外,row_data的格式可以是多种,我们需要将其转换为一个单行DataFrame。我们可以允许row_data是:-字典:键为列名,值为标量(因为只有一行)-Series:索引为列名,注意要转换成DataFrame并转置(因为Series是一维的,但我们需要一行)-列表或元组:需要与列数匹配,此时需要指定列名(但函数中我们不知道列名顺序,所以不推荐),因此我们要求用户传入的row_data最好是字典或Series,这样列名明确。如果传入的是列表或元组,那么我们必须要求用户同时传入列名列表?这样会使函数复杂。因此,我们规定row_data必须是字典或Series。实现步骤:1.处理新行数据:将row_data转换为DataFrame的一行,并设置索引为new_index。2.处理插入位置:如果insert_position大于df的行数,则将其设置为df的行数(即追加到最后)。3.使用pd.concat进行拼接。代码实现:</think>### 封装插入行函数(保留原始索引) 以下是将DataFrame插入行操作封装为可复用函数的实现方案: ```python import pandas as pd def insert_row_with_index(df, row_data, position, new_index=None): """ 在DataFrame指定位置插入新行并保留原始索引 参数: df -- 原始DataFrame row_data -- 新行数据(字典/Series,需包含所有列名) position -- 插入位置(整数,从0开始) new_index -- 新行的索引标签(默认自动生成唯一索引) 返回: 插入后的新DataFrame """ # 处理新行索引 if new_index is None: # 生成唯一索引(兼容数字和字符串索引) if df.index.inferred_type == 'integer': new_index = df.index.max() + 1 else: new_index = f"new_{len(df)}" # 创建新行DataFrame new_row = pd.DataFrame([row_data], index=[new_index]) # 处理边界位置 position = max(0, min(position, len(df))) # 分割并拼接DataFrame return pd.concat([ df.iloc[:position], # 插入位置的部分 new_row, # 新行 df.iloc[position:] # 插入位置后的部分 ]) ``` ### 函数使用示例 ```python # 创建示例DataFrame df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['x', 'y', 'z']) # 插入新行(自动生成索引) new_data = {'A': 9, 'B': 10} df_new = insert_row_with_index(df, new_data, position=1) # 插入新行(自定义索引) df_new_custom = insert_row_with_index(df, new_data, position=2, new_index="custom_idx") ``` ### 函数特性说明 1. **智能索引处理** - 自动检测索引类型生成唯一索引(整数索引递增,其他类型添加`new_`缀) - 支持自定义索引标签(确保与原始索引不冲突) 2. **边界安全保护** - 自动处理越界位置:`position < 0` 插入开头,`position > len(df)` 插入末尾 - 使用`min`/`max`保证位置值在合法范围内[^1] 3. **数据类型兼容** - 接受字典或Series格式的新行数据 - 保留原始列顺序(不依赖列名顺序) 4. **索引保留机制** - 使用`pd.concat`而非`append`避免索引重置 - 原DataFrame索引标签完全保持不变 ### 性能优化建议 当需要频繁插入多行时,可改用批量操作提升性能: ```python def batch_insert_rows(df, row_list, position_list, index_list=None): """批量插入多行(高效版)""" if index_list is None: index_list = [f"new_{i}" for i in range(len(row_list))] # 创建所有新行DataFrame new_rows = pd.DataFrame(row_list, index=index_list) # 单次拼接提升性能 return pd.concat([ df.iloc[:min(position_list)], new_rows, df.iloc[max(position_list):] ]).sort_index(level=0) # 保持原始行顺序 ``` ### 使用场景示例 ```python # 在金融数据中插入缺失交易日 stock_data = pd.DataFrame(...) # 索引为日期 missing_day = {'open': 102.5, 'high': 105.0, 'low': 101.0, 'close': 104.0} insert_row_with_index(stock_data, missing_day, position=15, new_index="2023-06-15") ``` > **提示**:此函数不会修改原始DataFrame,而是返回新对象,符合Pandas的不可变操作原则[^1]。如需就地修改,可赋值给原变量:`df = insert_row_with_index(df, ...)`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值