我有一个文本文件data.txt,其中包含一个表,其前几个条目如下所示:
PERIOD
CHANNELS 1 2 3 4 5
0 1.51 1.61 1.94 2.13 1.95
5 1.76 1.91 2.29 2.54 2.38
6 2.02 2.22 2.64 2.96 2.81
7 2.27 2.52 2.99 3.37 3.24
8 2.53 2.83 3.35 3.79 3.67
9 2.78 3.13 3.70 4.21 4.09
10 3.04 3.44 4.05 4.63 4.53...
通道列包含仪器通道的值。 其他5列包含特定频道可以在5个不同时间段内检测到的最大能量值。
我想编写一个python程序,该程序会获取周期,用户的较低能量和较高能量值,并基于该周期,找出与给定的较低能量值和较高能量值相对应的较低能量通道和较高能量通道由用户。
例如:
Period = input('Enter the period: ')
>> 1
lower_energy = float(input('Enter the lower energy value: '))
>> 2.02
higher_energy = float(input('Enter the higher energy value: '))
>> 2.60
The lower energy channel is 6
The higher energy channel is 9
我可以使用嵌套的if条件编写它,如下所示:
If period = 1:
if lower_energy < 1.51:
lower_energy_channel = 0
elif lower_energy < 1.76:
lower_energy_channel = 5
elif lower_energy < 2.02:
lower_energy_channel = 6
...
If upper_energy < 1.51:
upper_energy_channel = 0
elif upper_energy < 1.76:
upper_energy_channel = 5
...
在所有期间都一样...
但是我的桌子很长,非常麻烦。我正在寻找一种更清洁的解决方案。
可以找到解决方法 here
答案 0 :(得分:1)
@Neal ,请看下面的代码。我只是尝试用我的方式解决您的问题,并编写了一种方法来实现代码可重用性。
我使用了熊猫的DataFrame的概念来存储表格数据和有效地访问数据。
我已将您的给定数据存储在名为data.txt
的文件中。
PERIOD
CHANNELS 1 2 3 4 5
0 1.51 1.61 1.94 2.13 1.95
5 1.76 1.91 2.29 2.54 2.38
6 2.02 2.22 2.64 2.96 2.81
7 2.27 2.52 2.99 3.37 3.24
8 2.53 2.83 3.35 3.79 3.67
9 2.78 3.13 3.70 4.21 4.09
10 3.04 3.44 4.05 4.63 4.53
import numpy as np
import pandas as pd
def get_energy_details(file_name, period, low_energy, higher_energy, row_names=None, column_names=None):
# READ FILE AND STORE THE DATA IN 2D LIST
data_list = [] # FUTURE'S 2D LIST
with open(file_name) as f:
lines = f.readlines()[2:]
for line in lines:
arr = [float(num) for num in line.split()[1:]]
data_list.append(arr)
# PRINT 2D LIST
print (data_list, '\n')
# CREATING DataFrame FROM 2D LIST
df = pd.DataFrame(data_list, columns=column_names, index=row_names)
# PRINT DataFrame
print (df, '\n')
# SELECT THE SPECIFIC PERIOD (It is a Series object)
print (df[period])
# SORT THE SERIES AND STORE IT IN sorted_list
sorted_list = df[period].sort_values() # A Series object
# PRINT THE SORTED Series object
print (sorted_list)
# ************* MAIN LOGIC GOES HERE ****************
# ************* LOWER ENERGY ************************
found = False
low_energy_level = None
higher_energy_level = None
for i, item in enumerate(sorted_list):
print(i, item)
if low_energy_level is not None and higher_energy_level is not None:
break
if item <= low_energy:
low_energy_level = sorted_list.index[i]
if item >= higher_energy:
higher_energy_level = sorted_list.index[i]
# OUTPUT
return (low_energy_level, higher_energy_level)
# start
if __name__ == '__main__':
# INPUT 1
period1 = int(input('Enter the period: '))
lower_energy1 = float(input('Enter the lower energy value: '))
higher_energy1 = float(input('Enter the higher energy value: '))
row_names = [0, 5, 6, 7, 8, 9, 10]
column_names = [1, 2, 3, 4, 5]
energies1 = get_energy_details('data.txt', period1, lower_energy1, higher_energy1, row_names, column_names)
low_energy_level, higher_energy_level = energies1[0], energies1[1]
print('\nLower energy: ', low_energy_level, 'Higher energy: ', higher_energy_level, '\n\n');
# INPUT 2
period2 = int(input('Enter the period: '))
lower_energy2 = float(input('Enter the lower energy value: '))
higher_energy2 = float(input('Enter the higher energy value: '))
energies2 = get_energy_details('data.txt', period2, lower_energy2, higher_energy2)
low_energy_level, higher_energy_level = energies2[0], energies2[1]
print('\nLower energy: ', low_energy_level, 'Higher energy: ', higher_energy_level, '\n\n');
Enter the period: 1
Enter the lower energy value: 2.02
Enter the higher energy value: 2.60
[[1.51, 1.61, 1.94, 2.13, 1.95], [1.76, 1.91, 2.29, 2.54, 2.38], [2.02, 2.22, 2.64, 2.96, 2.81], [2.27, 2.52, 2.99, 3.37, 3.24], [2.53, 2.83, 3.35, 3.79, 3.67], [2.78, 3.13, 3.7, 4.21, 4.09], [3.04, 3.44, 4.05, 4.63, 4.53]]
1 2 3 4 5
0 1.51 1.61 1.94 2.13 1.95
5 1.76 1.91 2.29 2.54 2.38
6 2.02 2.22 2.64 2.96 2.81
7 2.27 2.52 2.99 3.37 3.24
8 2.53 2.83 3.35 3.79 3.67
9 2.78 3.13 3.70 4.21 4.09
10 3.04 3.44 4.05 4.63 4.53
0 1.51
5 1.76
6 2.02
7 2.27
8 2.53
9 2.78
10 3.04
Name: 1, dtype: float64
0 1.51
5 1.76
6 2.02
7 2.27
8 2.53
9 2.78
10 3.04
Name: 1, dtype: float64
0 1.51
1 1.76
2 2.02
3 2.27
4 2.53
5 2.78
6 3.04
Lower energy: 6 Higher energy: 9
Enter the period: 2
Enter the lower energy value: 2.96
Enter the higher energy value: 3.01
[[1.51, 1.61, 1.94, 2.13, 1.95], [1.76, 1.91, 2.29, 2.54, 2.38], [2.02, 2.22, 2.64, 2.96, 2.81], [2.27, 2.52, 2.99, 3.37, 3.24], [2.53, 2.83, 3.35, 3.79, 3.67], [2.78, 3.13, 3.7, 4.21, 4.09], [3.04, 3.44, 4.05, 4.63, 4.53]]
0 1 2 3 4
0 1.51 1.61 1.94 2.13 1.95
1 1.76 1.91 2.29 2.54 2.38
2 2.02 2.22 2.64 2.96 2.81
3 2.27 2.52 2.99 3.37 3.24
4 2.53 2.83 3.35 3.79 3.67
5 2.78 3.13 3.70 4.21 4.09
6 3.04 3.44 4.05 4.63 4.53
0 1.94
1 2.29
2 2.64
3 2.99
4 3.35
5 3.70
6 4.05
Name: 2, dtype: float64
0 1.94
1 2.29
2 2.64
3 2.99
4 3.35
5 3.70
6 4.05
Name: 2, dtype: float64
0 1.94
1 2.29
2 2.64
3 2.99
4 3.35
5 3.7
Lower energy: 2 Higher energy: 4
答案 1 :(得分:0)
好吧,那边有一张桌子!使其成为变量:
table = [[1.51, 1.61, 1.94, 2.13, 1.95],
[1.76, 1.91, 2.29, 2.54, 2.38],
[2.02, 2.22, 2.64, 2.96, 2.81],
...
[3.04, 3.44, 4.05, 4.63, 4.53]]
这实际上是一个二维python列表。您可以通过创建更多列表来“标记轴”来走得更远,可以这么说:
period_axis = [1, 2, 3, 4, 5]
channel_axis = [0, 5, 6, 7, 8, 9, 10]
现在您可以使用一个重复 if
语句而不是几个类似的语句遍历该数组:
period_idx = period_axis.index(period) # Find table column corresponding to input
period_column = [row[0] for row in table] # Use list comprehension to get a list
# comprised of JUST the column we want
lower_energy_idx = 0 # Initialize lower_energy_channel index
for i in range(len(period_column)): # Iterate through period_column by index
if lower_energy < period_column[i]: # This is your if statement from above
lower_energy_idx = i
lower_energy_channel = channel_axis[i] # use the channel axis to translate index
# back into a useful number
...
Python的索引为0,因此必须使用period_axis
和channel_axis
才能将python的表索引转换为表的索引。而且我不确定我是否完全理解您的示例,因为这不会一次查看多个列。但是这里的总体思路应该或多或少清楚:您可以根据需要创建一个表并对其进行迭代,而不是使用一堆if
语句。可能不会完全删除if
语句,但至少会减少您必须使用的语句量。