Python - добавить значение str к определенным строкам в DataFrame
У меня есть значение, которое я сохранил в строке. Я хотел бы добавить это значение только к строкам, которые соответствуют определенным критериям, а не к каким-либо другим.
На следующем рисунке показаны таблицы, которые мне нужно проанализировать. Я могу легко разобрать файл с BeautifulSoup
и превратить его в Pandas
DataFrame, но для обеих таблиц ниже я пытаюсь захватить и добавить Package
цены на весь DataFrame. В идеале значения цены должны сочетаться с каждой парой рыба-вес; поэтому один столбец с одинаковым значением Price.
Вот код, который я использую для разбора таблиц:
with open(file_path) as in_f:
msg = email.message_from_file(in_f) #type: <class 'email.message.Messgae'>
html_msg = msg.get_payload(1) #type: <class 'email.message.Message'>
body = html_msg.get_payload(decode=True) #type: <class 'bytes'> or type: 'int'
html = body.decode() #type: <class 'str'>
tablez = BeautifulSoup(html).find_all("table") #type: <class 'bs4.element.ResultSet'>
data = []
for table in tablez:
for row in table.find_all("tr"):
data.append([cell.text.strip() for cell in row.find_all("td")])
fish_frame = pd.DataFrame(data)
Это то, что data
является:
data: [['Species', 'Price', 'Weight'], ['GBW Cod', '.55', '8,059'], ['GBE Haddock', '.03', '14,628'], ['GBW Haddock', '.02', '87,451'], ['GB YT', '1.50', '1,818'], ['Witch', '1.25', '1,414'], ['GB Winter', '.40', '23,757'], ['Redfish', '.02', '123'], ['White Hake', '.40', '934'], ['Pollock', '.02', '7,900'], ['Package Price:', '', '$21,151.67'], ['Species', 'Weight'], ['GBE Cod', '820'], ['GBW Cod', '15,279'], ['GBE Haddock', '32,250'], ['GBW Haddock', '192,793'], ['GB YT', '6,239'], ['SNE YT', '2,018'], ['GOM YT', '1,511'], ['Plaice', '2,944'], ['Witch', '1,100'], ['GB Winter', '158,608'], ['White Hake', '31'], ['Pollock', '1,983'], ['SNE Winter', '7,257'], ['Price', '$58,500.00'], ['Species', 'Weight'], ['GBE Cod', '792'], ['GBW Cod', '14,767'], ['GBE Haddock', '29,199'], ['GBW Haddock', '174,556'], ['GB YT', '5,268'], ['SNE YT', '544'], ['GOM YT', '1,957'], ['Plaice', '2,452'], ['Witch', '896'], ['GB Winter', '163,980'], ['White Hake', '8'], ['Pollock', '1,743'], ['SNE Winter', '3,709'], ['Price', '$57,750.00']]
А потом я использую этот кусок кода, чтобы захватить Package
цена:
stew = BeautifulSoup(html, 'html.parser')
chunks = stew.find_all('p', {'class' : "MsoNormal"})
for line in chunks:
if 'Package' in line.text:
package_price = line.text
print("package_price:", package_price)
Но сейчас я пытаюсь добавить это значение Price к своему собственному столбцу в кадре данных. Выполнение команды, такой как fish_frame = pd.DataFrame(package_price)
результаты в:
Traceback (most recent call last):
File "Z:/Code/NEFS_stock_then_weight_attempt3.py", line 236, in <module>
fish_frame = pd.DataFrame(package_price)
File "C:\Users\stephen.mahala\AppData\Local\Programs\Python\Python35-32\lib\site-packages\pandas\core\frame.py", line 345, in __init__
raise PandasError('DataFrame constructor not properly called!')
pandas.core.common.PandasError: DataFrame constructor not properly called!
по причинам, которые мне неизвестны. Превращая это в list
однако, это приводит к тому, что строка разбивается, и каждый символ становится отдельным списком, и поэтому каждый из них становится своей собственной ячейкой в DataFrame.
Есть ли метод с Pandas
или с BeautifulSoup
что я не знаю, что упростит процесс добавления этого единственного значения в мой DataFrame?
1 ответ
Когда я создаю ваш fish_frame
от pd.DataFrame(data)
Я получаю следующее, которое состоит из обоих наборов табличных данных:
0 1 2
0 Species Price Weight
1 GBW Cod .55 8,059
2 GBE Haddock .03 14,628
3 GBW Haddock .02 87,451
4 GB YT 1.50 1,818
5 Witch 1.25 1,414
6 GB Winter .40 23,757
7 Redfish .02 123
8 White Hake .40 934
9 Pollock .02 7,900
10 Package Price: $21,151.67
11 Species Weight None
12 GBE Cod 820 None
13 GBW Cod 15,279 None
14 GBE Haddock 32,250 None
15 GBW Haddock 192,793 None
16 GB YT 6,239 None
17 SNE YT 2,018 None
18 GOM YT 1,511 None
19 Plaice 2,944 None
20 Witch 1,100 None
21 GB Winter 158,608 None
22 White Hake 31 None
23 Pollock 1,983 None
24 SNE Winter 7,257 None
25 Price $58,500.00 None
26 Species Weight None
27 GBE Cod 792 None
28 GBW Cod 14,767 None
29 GBE Haddock 29,199 None
30 GBW Haddock 174,556 None
31 GB YT 5,268 None
32 SNE YT 544 None
33 GOM YT 1,957 None
34 Plaice 2,452 None
35 Witch 896 None
36 GB Winter 163,980 None
37 White Hake 8 None
38 Pollock 1,743 None
39 SNE Winter 3,709 None
40 Price $57,750.00 None
Если вы избавитесь от внешней петли for table in tablez:
и просто сделать for row in tablez[0]
Я думаю, что вы закончите с:
data = [['Species', 'Price', 'Weight'], ['GBW Cod', '.55', '8,059'],
['GBE Haddock', '.03', '14,628'], ['GBW Haddock', '.02', '87,451'],
['GB YT', '1.50', '1,818'], ['Witch', '1.25', '1,414'],
['GB Winter', '.40', '23,757'], ['Redfish', '.02', '123'],
['White Hake', '.40', '934'], ['Pollock', '.02', '7,900'],
['Package Price:', '', '$21,151.67']]
А потом fish_frame=pd.DataFrame(data)
приведет к:
0 1 2
0 Species Price Weight
1 GBW Cod .55 8,059
2 GBE Haddock .03 14,628
3 GBW Haddock .02 87,451
4 GB YT 1.50 1,818
5 Witch 1.25 1,414
6 GB Winter .40 23,757
7 Redfish .02 123
8 White Hake .40 934
9 Pollock .02 7,900
10 Package Price: $21,151.67
Внесите ли вы это изменение или нет, это добавит столбец к fish_frame
:
srs = pd.Series([package_price]*len(fish_frame))
fish_frame[3] = pd.Series(srs,index=fish_frame.index)
И тогда вы должны получить:
0 1 2 3
0 Species Price Weight #891-2: Package for $21,151.67 but willing to sell species individually
1 GBW Cod .55 8,059 #891-2: Package for $21,151.67 but willing to sell species individually
2 GBE Haddock .03 14,628 #891-2: Package for $21,151.67 but willing to sell species individually
3 GBW Haddock .02 87,451 #891-2: Package for $21,151.67 but willing to sell species individually
4 GB YT 1.50 1,818 #891-2: Package for $21,151.67 but willing to sell species individually
...